home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #9 / Amiga Plus CD - 2004 - No. 09.iso / amigaplus / games / saga / source / engine.c < prev    next >
Encoding:
C/C++ Source or Header  |  2004-08-03  |  152.7 KB  |  4,140 lines

  1. // 1. INCLUDES -----------------------------------------------------------
  2.  
  3. #include <exec/types.h>
  4.  
  5. #include <clib/locale_protos.h>
  6.  
  7. #include <stdio.h>                     // sprintf()
  8. #include <stdlib.h>                    // rand()
  9. #include <string.h>                    // strcpy(), strcat()
  10. // #include <assert.h>
  11.  
  12. #include "saga.h"
  13.  
  14. #define CATCOMP_NUMBERS
  15. #include "saga_strings.h"
  16.  
  17. // 2. DEFINES ------------------------------------------------------------
  18.  
  19. #define NORMAL  0
  20. #define GOOD    1
  21. #define BAD     2
  22.  
  23. #define HAGALL  1
  24. #define IS      2
  25. #define JARA    3
  26. #define NIED    4
  27. #define WYNN    5
  28. #define YR      6
  29.  
  30. #define DRAGON  0
  31. #define DROW    1
  32. #define GIANT   2
  33. #define GHOST   3
  34. #define TROLL   4
  35. #define WITCH   5
  36. #define HYDRA   6
  37. #define SERPENT 7
  38.  
  39. // 3. EXPORTED VARIABLES -------------------------------------------------
  40.  
  41. AGLOBAL struct RuneStruct rune[RUNES + 1] =
  42. { { "Amsir"},
  43.   { "Eon"  },
  44.   { "Geofu"},
  45.   { "Ing"  },
  46.   { "Ogal" },
  47.   { "Sygil"}
  48. };
  49. AGLOBAL struct JarlStruct jarl[JARLS + 1] =
  50. { { 2, 3, "Amleth"    },
  51.   { 3, 3, "Bjarki"    },
  52.   { 3, 3, "Erik"      },
  53.   { 2, 2, "Eyjolf"    },
  54.   { 3, 2, "Gretter"   },
  55.   { 2, 2, "Hagen"     },
  56.   { 2, 3, "Harald"    },
  57.   { 2, 3, "Helgi"     },
  58.   { 2, 2, "Hengist"   },
  59.   { 2, 2, "Horsi"     },
  60.   { 4, 2, "Hrolfwulf" },
  61.   { 4, 2, "Ivar"      },
  62.   { 4, 3, "Kari"      },
  63.   { 2, 3, "Skallagrim"},
  64.   { 3, 3, "Thorolf"   },
  65.   { 2, 3, "Thorvald"  },
  66.   { 3, 3, "Welland"   },
  67.   { 3, 3, "Wiglar"    }
  68. };
  69.  
  70. /* 1 x 4-3 .
  71.    2 x 4-2 ..
  72.    5 x 3-3 .....
  73.    1 x 3-2 .
  74.    5 x 2-3 .....
  75.    4 x 2-2 ....
  76.  
  77.                    11 have move   of 3, 7 have move   of 2.
  78. 3 have attack of 4, 6 have attack of 3, 9 have attack of 2. */
  79.  
  80. AGLOBAL struct HeroStruct hero[HEROES + 1];
  81. AGLOBAL struct SordStruct sord[SORDS + 1] =
  82. { { "Balmung (+1)"    ,  20},
  83.   { "Dragvendill (+2)",  90},
  84.   { "Gram (+2)"       , 120},
  85.   { "Hrunting (+1)"   , 150},
  86.   { "Lovi (+1)"       , 200},
  87.   { "Tyrfing (+2)"    , 250}
  88. };
  89.  
  90. AGLOBAL struct TreasureStruct treasure[TREASURES + 1] =
  91. { {""         ,  20},
  92.   {"Frey Faxi", 110},
  93.   {""         , 160},
  94.   {""         , 210},
  95.   {""         , 260},
  96.   {""         , 310}
  97. };
  98.  
  99. AGLOBAL struct MonsterStruct monster[MONSTERS + 1] =
  100. { { DRAGON, 10, 1, "Aludreng" },
  101.   { DRAGON, 11, 2, "Fafnir"   },
  102.   { DRAGON, 10, 2, "Glerion"  },
  103.   { DRAGON, 10, 2, "Hallbjorn"},
  104.   { DRAGON,  9, 3, "Istvan"   },
  105.   { DRAGON, 11, 2, "Stigandi" },
  106.   { DROW,    2, 2, "Atli"     },
  107.   { DROW,    3, 1, "Gizur"    },
  108.   { DROW,    3, 1, "Hallgerd" },
  109.   { GHOST,   4, 2, "Gizar"    },
  110.   { GHOST,   4, 1, "Glam"     },
  111.   { GHOST,   4, 0, "Gunnar"   },
  112.   { GHOST,   4, 0, "Hrap"     },
  113.   { GHOST,   4, 1, "Mord"     },
  114.   { GHOST,   4, 1, "Trogrier" },
  115.   { GIANT,   7, 0, "Angantyr" },
  116.   { GIANT,   6, 1, "Hall"     },
  117.   { GIANT,   8, 1, "Storvick" },
  118.   { TROLL,   6, 2, "Grendall" },
  119.   { TROLL,   5, 2, "Hallbjorn"},
  120.   { TROLL,   5, 1, "Hauk"     },
  121.   { TROLL,   6, 1, "Hogshead" },
  122.   { TROLL,   5, 3, "Onund"    },
  123.   { TROLL,   5, 2, "Svinafell"},
  124.   { WITCH,   3, 4, "Gerdrak"  },
  125.   { WITCH,   3, 5, "Grunhild" },
  126.   { WITCH,   4, 4, "Hedin"    },
  127.   { HYDRA,  12, 1, "Anschar"  },
  128.   { HYDRA,  13, 1, "Hardrada" },
  129.   {SERPENT, 12, 2, "Olaf"     },
  130.   {SERPENT, 13, 1, "Petro"    }
  131. };
  132.  
  133. /* These are the statistical distribution of the taxation factors:
  134.     4x  2 tax
  135.    10x  3 tax
  136.     3x  4 tax
  137.     3x  5 tax
  138.     6x  6 tax
  139.     4x  7 tax
  140.     1x  8 tax
  141.     2x  9 tax
  142.     3x 10 tax */
  143.  
  144. AGLOBAL struct WorldStruct world[36 + 30] =
  145. {   {590, TBSIZE +  39,  3, LAND,      "Finmark"  ,       1, -1, -1, -1, -1, -1, -1, -1}, // 1:1 ( 0) (inland)
  146.     {584, TBSIZE + 104,  3, LAND,      "Trondheim",       0,  2,  3, 60, -1, -1, -1, -1}, // 1:2 ( 1)
  147.     {489, TBSIZE + 102,  6, LAND,      "Mordaland",       1,  3,  4, 55, 59, 60, -1, -1}, // 1:3 ( 2)
  148.     {573, TBSIZE + 173,  2, LAND,      "Upland",          1,  2,  4,  5,  6, -1, -1, -1}, // 1:4 ( 3) (inland)
  149.     {451, TBSIZE + 176,  5, LAND,      "Agdar",           2,  3,  5, 48, 49, 54, 55, -1}, // 1:5 ( 4)
  150.     {514, TBSIZE + 201,  3, LAND,      "Romeirt",         3,  4,  6,  7, 47, 48, -1, -1}, // 1:6 ( 5)
  151.     {569, TBSIZE + 233,  7, LAND,      "Jamtland",        3,  5,  7,  8, 65, -1, -1, -1}, // 2:1 ( 6)
  152.     {512, TBSIZE + 262,  6, LAND,      "Vester Gotland",  5,  6,  8,  9, 47, -1, -1, -1}, // 2:2 ( 7)
  153.     {549, TBSIZE + 305,  7, LAND,      "Oster Gotland",   6,  7,  9, 63, 65, -1, -1, -1}, // 2:3 ( 8)
  154.     {502, TBSIZE + 323,  4, LAND,      "Suder Gotland",   7,  8, 11, 47, 63, -1, -1, -1}, // 2:4 ( 9)
  155.     {420, TBSIZE + 287,  6, LAND,      "Juteland",       11, 14, 46, 47, 48, 49, -1, -1}, // 2:5 (10)
  156.     {441, TBSIZE + 344,  3, ISLE,      "Scandia",         9, 10, 12, 13, 14, 47, 63, -1}, // 2:6 (11)
  157.     {522, TBSIZE + 442,  4, LAND,      "Pomerania",      11, 13, 63, 64, -1, -1, -1, -1}, // 3:1 (12)
  158.     {393, TBSIZE + 421,  6, LAND,      "Saxony",         11, 12, 14, 15, 16, 46, -1, -1}, // 3:2 (13)
  159.     {392, TBSIZE + 372,  7, LAND,      "Anglia",         10, 11, 13, 46, -1, -1, -1, -1}, // 3:3 (14)
  160.     {305, TBSIZE + 383,  7, LAND,      "Fenland",        13, 16, 17, 44, 45, 46, -1, -1}, // 3:4 (15)
  161.     {305, TBSIZE + 434, 10, LAND,      "Rhineland",      13, 15, 17, -1, -1, -1, -1, -1}, // 3:5 (16) (inland)
  162.     {242, TBSIZE + 428,  9, LAND,      "Frisia",         15, 16, 18, 44, -1, -1, -1, -1}, // 3:6 (17)
  163.     {175, TBSIZE + 438,  3, LAND,      "Frankland",      17, 19, 43, 44, -1, -1, -1, -1}, // 4:1 (18)
  164.     { 97, TBSIZE + 439, 10, LAND,      "Armorica",       18, 42, 43, -1, -1, -1, -1, -1}, // 4:2 (19)
  165.     { 75, TBSIZE + 318,  2, LAND,      "Cornwall",       21, 42, 43, -1, -1, -1, -1, -1}, // 4:3 (20)
  166.     {109, TBSIZE + 333, 10, LAND,      "Wessex",         20, 22, 23, 24, 25, 42, 43, -1}, // 4:4 (21)
  167.     {153, TBSIZE + 354,  9, LAND,      "Sussex",         21, 23, 24, 43, 44, -1, -1, -1}, // 4:5 (22)
  168.     {190, TBSIZE + 329,  6, LAND,      "East Anglia",    22, 24, 44, 45, -1, -1, -1, -1}, // 4:6 (23)
  169.     {148, TBSIZE + 313,  3, LAND,      "Mercia",         21, 22, 23, 25, 26, 27, 45, 51}, // 5:1 (24)
  170.     {108, TBSIZE + 287,  3, LAND,      "Daffyd",         21, 24, 26, 41, 42, -1, -1, -1}, // 5:2 (25)
  171.     {145, TBSIZE + 268,  2, LAND,      "Gwynedd",        24, 25, 27, 41, -1, -1, -1, -1}, // 5:3 (26)
  172.     {186, TBSIZE + 217,  8, LAND,      "Northumberland", 24, 26, 28, 41, 51, 52, -1, -1}, // 5:4 (27)
  173.     {178, TBSIZE + 157,  3, LAND,      "Dalriada",       27, 29, 30, 40, 41, 52, -1, -1}, // 5:5 (28)
  174.     {222, TBSIZE + 130,  5, LAND,      "Caledonia",      28, 30, 52, 57, -1, -1, -1, -1}, // 5:6 (29)
  175.     {230, TBSIZE +  85,  2, PENINSULA, "Pictland",       28, 29, 31, 40, 57, 58, 61, 62}, // 6:1 (30)
  176.     {167, TBSIZE +  66,  3, ISLE,      "Hebrides",       30, 36, 39, 40, 62, -1, -1, -1}, // 6:2 (31)
  177.     { 62, TBSIZE +  40,  3, LAND,      "Thule",          36, 37, -1, -1, -1, -1, -1, -1}, // 6:3 (32)
  178.     { 54, TBSIZE + 162,  5, LAND,      "Connacht",       34, 35, 38, 39, -1, -1, -1, -1}, // 6:4 (33)
  179.     {109, TBSIZE + 162,  4, LAND,      "Ulster",         33, 35, 39, 40, 41, -1, -1, -1}, // 6:5 (34)
  180.     { 60, TBSIZE + 203,  6, LAND,      "Leinster",       33, 34, 41, -1, -1, -1, -1, -1}, // 6:6 (35)
  181.     {134, TBSIZE +  32,  0, SEA,       "",               31, 32, 37, 39, -1, -1, -1, -1}, //     (36)
  182.     { 52, TBSIZE +  94,  0, SEA,       "",               32, 36, 38, 39, -1, -1, -1, -1}, //     (37)
  183.     { 53, TBSIZE + 130,  0, SEA,       "",               33, 37, 39, -1, -1, -1, -1, -1}, //     (38)
  184.     { 82, TBSIZE + 118,  0, SEA,       "",               31, 33, 34, 36, 37, 38, 40, -1}, //     (39)
  185.     {137, TBSIZE + 165,  0, SEA,       "",               28, 30, 31, 34, 39, 41, -1, -1}, //     (40)
  186.     {116, TBSIZE + 225,  0, SEA,       "",               25, 26, 27, 28, 34, 35, 40, 42}, //     (41)
  187.     { 57, TBSIZE + 292,  0, SEA,       "",               19, 20, 21, 25, 41, 43, -1, -1}, //     (42)
  188.     {127, TBSIZE + 389,  0, SEA,       "",               18, 19, 20, 21, 22, 42, 44, -1}, //     (43)
  189.     {217, TBSIZE + 370,  0, SEA,       "",               15, 17, 18, 22, 23, 43, 45, -1}, //     (44)
  190.     {261, TBSIZE + 328,  0, SEA,       "",               15, 23, 24, 44, 46, 50, 51, -1}, //     (45)
  191.     {343, TBSIZE + 334,  0, SEA,       "",               10, 13, 14, 15, 45, 49, 50, -1}, //     (46)
  192.     {467, TBSIZE + 282,  0, SEA,       "Kategatt",        5,  7,  9, 10, 11, 48, -1, -1}, //     (47)
  193.     {445, TBSIZE + 229,  0, SEA,       "Skagerrak",       4,  5, 10, 47, 49, -1, -1, -1}, //     (48)
  194.     {376, TBSIZE + 270,  0, SEA,       "",                4, 10, 48, 46, 50, 54, -1, -1}, //     (49)
  195.     {311, TBSIZE + 268,  0, SEA,       "",               45, 46, 49, 51, 53, 54, -1, -1}, //     (50) (deep waters)
  196.     {240, TBSIZE + 258,  0, SEA,       "",               24, 27, 45, 50, 52, 53, -1, -1}, //     (51)
  197.     {248, TBSIZE + 193,  0, SEA,       "",               27, 28, 29, 51, 53, 56, 57, -1}, //     (52)
  198.     {324, TBSIZE + 196,  0, SEA,       "",               50, 51, 52, 54, 55, 56, -1, -1}, //     (53) (deep waters)
  199.     {379, TBSIZE + 186,  0, SEA,       "",                4, 49, 50, 53, 55, -1, -1, -1}, //     (54)
  200.     {386, TBSIZE + 124,  0, SEA,       "",                2,  4, 53, 54, 56, 58, 59, -1}, //     (55)
  201.     {318, TBSIZE + 134,  0, SEA,       "",               52, 53, 55, 57, 58, -1, -1, -1}, //     (56) (deep waters)
  202.     {267, TBSIZE + 133,  0, SEA,       "",               29, 30, 52, 56, 58, -1, -1, -1}, //     (57)
  203.     {338, TBSIZE +  90,  0, SEA,       "",               30, 55, 56, 57, 59, 60, 61, -1}, //     (58)
  204.     {427, TBSIZE +  73,  0, SEA,       "",                2, 55, 58, 60, -1, -1, -1, -1}, //     (59)
  205.     {456, TBSIZE +  27,  0, SEA,       "",                1,  2, 58, 59, 61, -1, -1, -1}, //     (60)
  206.     {341, TBSIZE +  47,  0, SEA,       "",               30, 58, 60, 62, -1, -1, -1, -1}, //     (61)
  207.     {257, TBSIZE +  44,  0, SEA,       "",               30, 31, 61, -1, -1, -1, -1, -1}, //     (62)
  208.     {509, TBSIZE + 385,  0, SEA,       "",                8,  9, 11, 12, 64, 65, -1, -1}, //     (63)
  209.     {587, TBSIZE + 404,  0, SEA,       "",               12, 63, 65, -1, -1, -1, -1, -1}, //     (64)
  210.     {587, TBSIZE + 345,  0, SEA,       "",                6,  8, 63, 64, -1, -1, -1, -1}  //     (65)
  211. };
  212.  
  213. // 4. IMPORTED VARIABLES -------------------------------------------------
  214.  
  215. IMPORT struct LocaleInfo     li;
  216. IMPORT TEXT                  onekey[ONEKEYS + 1],
  217.                              saystring[256 + 1],
  218.                              saystring2[256 + 1],
  219.                              numberstring[13 + 1],
  220.                              label[17 + 1][40 + 1],
  221.                              line[2][MAXLINES + 1][80 + 1];
  222. IMPORT STRPTR                monstertypes[8];
  223. IMPORT SLONG                 faxirides, monsters, treasures;
  224.  
  225. // 5. MODULE VARIABLES ---------------------------------------------------
  226.  
  227. MODULE SLONG                 order[HEROES + 1];
  228.                              whichmove,
  229.                              whichrealmove,
  230.                              movearray[66];
  231. MODULE FLAG                  freemove;
  232.  
  233. // 6. MODULE STRUCTURES --------------------------------------------------
  234.  
  235. // 7. MODULE FUNCTIONS ---------------------------------------------------
  236.  
  237. MODULE void callforaid(SLONG passedtype, SLONG passed);
  238. MODULE FLAG recruit(SLONG recruited, SLONG recruiterhero);
  239. MODULE void flee(SLONG routertype, SLONG router, SLONG routerhero, SLONG routedtype, SLONG routed, SLONG routedhero);
  240. MODULE void wound(SLONG woundertype, SLONG wounder, SLONG wounderhero, SLONG woundedtype, SLONG wounded, SLONG woundedhero);
  241. MODULE void kill(SLONG killertype, SLONG killer, SLONG killerhero, SLONG killedtype, SLONG killed, SLONG killedhero);
  242. MODULE void dobattle(SLONG defendtype, SLONG defender, SLONG attackhero);
  243. MODULE SLONG d6(void);
  244. MODULE void attack(SLONG whichhero);
  245. MODULE void gain(SLONG whichhero, SLONG glory, SLONG luck);
  246. MODULE void move(SLONG whichhero);
  247. MODULE SLONG getluck(SLONG whichhero);
  248. MODULE void amiga_rout(SLONG routed, SLONG routedtype);
  249. MODULE void human_rout(SLONG routedtype, SLONG routed, SLONG routerhero);
  250. MODULE SLONG getmoves(SLONG countertype, SLONG whichcounter, FLAG freyfaxi);
  251. MODULE void thor(SLONG whichhero);
  252. MODULE void cast(SLONG caster, SLONG whichspell);
  253. MODULE void getdefender(SLONG attackhero, SLONG here);
  254. MODULE void needsord(SLONG countertype, SLONG counter, SLONG whichcountry, SLONG control);
  255. MODULE void brosung(SLONG countertype, SLONG whichcounter, SLONG control);
  256. MODULE void needtreasure(SLONG countertype, SLONG counter, SLONG whichcountry, SLONG control);
  257. MODULE void amiga_attack(SLONG attackhero, SLONG defendtype, SLONG defender, SLONG whichcountry);
  258. MODULE FLAG ask_treasure(SLONG countertype, SLONG whichcounter, SLONG whichtreasure);
  259. MODULE FLAG attackersleft(void);
  260. MODULE void dospell(SLONG spell, SLONG caster);
  261. MODULE SLONG getattackers(SLONG whichhero, SLONG whichcountry, FLAG real);
  262. MODULE SLONG odin_tyr(LONG whichhero, FLAG attacking);
  263. MODULE void gods(SLONG whichhero);
  264. MODULE void pray(SLONG whichhero);
  265. MODULE void conquer(SLONG conquerortype, SLONG conqueror, SLONG conquerorhero, SLONG whichcountry);
  266. MODULE void findtreasure(SLONG victortype, SLONG victor, SLONG victorhero, SLONG whichmonster);
  267. MODULE void drop(SLONG droppertype, SLONG dropper, SLONG whichcountry);
  268. MODULE FLAG islegal(SLONG movertype, SLONG mover, SLONG whichcountry, FLAG human);
  269. MODULE FLAG checkfree(SLONG whichhero, FLAG* freemove);
  270. MODULE FLAG needitem(SLONG countertype, SLONG counter, SLONG whichcountry);
  271. MODULE FLAG autosense(SLONG player);
  272. MODULE FLAG findattackers(SLONG player, SLONG whichcountry, SLONG victimtype, SLONG victim);
  273. MODULE void deselect_combatants(SLONG attackhero, SLONG defendtype, SLONG defendhero, SLONG defender);
  274. MODULE SLONG assess_hero(SLONG whichhero, SLONG whichcountry);
  275. MODULE SLONG assess_jarl(SLONG whichjarl, SLONG whichcountry);
  276. MODULE SLONG countjarls(SLONG whichhero);
  277. MODULE void onemove_hero(SLONG whichhero, SLONG whichcountry);
  278. MODULE void onemove_jarl(SLONG whichjarl, SLONG whichcountry);
  279. MODULE SLONG checkdefenders_hero(SLONG whichhero, SLONG whichcountry);
  280. MODULE SLONG checkdefenders_jarl(SLONG whichhero, SLONG whichcountry);
  281. MODULE void givegold(SLONG whichhero, SLONG whichjarl);
  282.  
  283. // 8. CODE ---------------------------------------------------------------
  284.  
  285. AGLOBAL void place_monsters(void)
  286. {   /* .taken = FALSE: the monster is in the "pile of monsters" (spare).
  287.                 TRUE : the monster is either on the board or dead. */
  288.  
  289.     SLONG whichhero, whichmonster, whichtreasure;
  290.     FLAG  available, ok;
  291.  
  292.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  293.     {   if (hero[whichhero].alive)
  294.         {   available = FALSE;
  295.             for (whichmonster = 0; whichmonster <= monsters; whichmonster++)
  296.             {   if (!monster[whichmonster].taken)
  297.                 {   available = TRUE;
  298.                     break;
  299.             }   }
  300.             if (available)
  301.             {   do
  302.                 {   whichmonster = rand() % (monsters + 1);
  303.                 } while (monster[whichmonster].taken);
  304.                 monster[whichmonster].taken    =
  305.                 monster[whichmonster].alive    = TRUE;
  306.  
  307.                 if (monster[whichmonster].species == SERPENT)
  308.                 {   monster[whichmonster].where    = (rand() % 30) + 36;
  309.                 } else
  310.                 {   monster[whichmonster].where    = rand() % 36;
  311.                 }
  312.  
  313.                 monster[whichmonster].sea      = NORMAL;
  314.                 monster[whichmonster].hagall   = FALSE;
  315.  
  316.                 if (monster[whichmonster].species == DRAGON)
  317.                 {   ok = FALSE;
  318.                     for (whichtreasure = 0; whichtreasure <= treasures; whichtreasure++)
  319.                     {   if (!treasure[whichtreasure].taken)
  320.                         {   ok = TRUE; // at least one treasure is available
  321.                             break; // for speed
  322.                     }   }
  323.                     if (ok)
  324.                     {   do
  325.                         {   whichtreasure = rand() % (treasures + 1);
  326.                         } while (treasure[whichtreasure].taken);
  327.                         treasure[whichtreasure].taken         = TRUE;
  328.                         treasure[whichtreasure].possessortype = MONSTER;
  329.                         treasure[whichtreasure].possessor     = whichmonster;
  330.                         treasure[whichtreasure].where         = -1;
  331.  
  332.                         monster[whichmonster].wealth = 0;
  333.                     } else
  334.                     {   monster[whichmonster].wealth = 20;
  335.                 }   }
  336.                 elif (monster[whichmonster].species == HYDRA)
  337.                 {   monster[whichmonster].wealth = 30;
  338.                 } else
  339.                 {   monster[whichmonster].wealth = 0;
  340.                 }
  341.                 // we don't unslot newborn counters
  342.                 move_monster(whichmonster, FALSE);
  343. }   }   }   }
  344.  
  345. AGLOBAL void place_jarls(void)
  346. {   FLAG  available;
  347.     SLONG whichhero, whichjarl;
  348.  
  349.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  350.     {   if (hero[whichhero].alive)
  351.         {   available = FALSE;
  352.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  353.             {   if (!jarl[whichjarl].taken)
  354.                 {   available = TRUE;
  355.                     break;
  356.             }   }
  357.             if (available)
  358.             {   do
  359.                 {   whichjarl = rand() % (JARLS + 1);
  360.                 } while (jarl[whichjarl].taken);
  361.                 jarl[whichjarl].taken     =
  362.                 jarl[whichjarl].alive     = TRUE;
  363.                 jarl[whichjarl].wealth    = 0;
  364.                 jarl[whichjarl].where     =
  365.                 jarl[whichjarl].homewhere = rand() % 36;
  366.                 jarl[whichjarl].hero      = -1;
  367.                 jarl[whichjarl].sea       = NORMAL;
  368.                 jarl[whichjarl].hagall    =
  369.                 jarl[whichjarl].loseturn  = FALSE;
  370.                 hidejarl(whichjarl, FALSE);
  371.                 // we don't unslot newborn counters
  372.                 move_jarl(whichjarl, FALSE);
  373. }   }   }   }
  374.  
  375. MODULE void callforaid(SLONG passedtype, SLONG passed)
  376. {   SLONG passedhero, passedwhere, whichjarl;
  377.  
  378.     if (passedtype == HERO)
  379.     {   passedhero = passed;
  380.         passedwhere = hero[passed].where;
  381.     } else
  382.     {   // assert(passedtype == JARL);
  383.         // assert(jarl[passed].hero != -1);
  384.         passedhero = jarl[passed].hero;
  385.         passedwhere = jarl[passed].where;
  386.     }
  387.  
  388.     if (passedtype == JARL && hero[passedhero].where == passedwhere)
  389.     {   hero[passedhero].defending = TRUE;
  390.         select_hero(passedhero, FALSE);
  391.     }
  392.  
  393.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  394.     {   if
  395.         (   jarl[whichjarl].hero == passedhero
  396.          && jarl[whichjarl].where == passedwhere
  397.          && !jarl[whichjarl].defending
  398.         )
  399.         {   jarl[whichjarl].defending = TRUE;
  400.             select_jarl(whichjarl, FALSE);
  401.     }   }
  402.  
  403.     refreshcounters();
  404. }
  405.  
  406. MODULE void dobattle(SLONG defendtype, SLONG defender, SLONG attackhero)
  407. {   SLONG decision,
  408.           result,
  409.           attackluck     = 0,
  410.           attackstrength = 0,
  411.           attacktype,
  412.           attacker       = -1, // to avoid spurious compiler warnings
  413.           defendluck     = 0,
  414.           defendstrength = 0,
  415.           defendhero     = -1, // to avoid spurious compiler warnings
  416.           whichhero,
  417.           whichjarl,
  418.           whichsord;
  419.  
  420.     /* defendtype: type of defender, one of HERO, JARL, MONSTER or KINGDOM.
  421.        defender: ordinal number of defender. */
  422.  
  423.     switch (defendtype)
  424.     {
  425.     case HERO:
  426.         defendhero = defender;
  427.         hero[defender].defending = TRUE;
  428.         select_hero(defender, FALSE);
  429.         callforaid(HERO, defender);
  430.     break;
  431.     case JARL:
  432.         defendhero = jarl[defender].hero;
  433.         jarl[defender].defending = TRUE;
  434.         if (defendhero != -1)
  435.         {   select_jarl(defender, FALSE);
  436.             callforaid(JARL, defender);
  437.         } else
  438.         {   select_jarl(defender, TRUE);
  439.         }
  440.     break;
  441.     case MONSTER:
  442.         select_monster(defender, TRUE);
  443.         defendstrength = monster[defender].strength;
  444.         defendhero = -1;
  445.     break;
  446.     case KINGDOM:
  447.         defendstrength = world[defender].tax;
  448.         defendhero = -1; // even if it already has a king it makes no difference to the combat
  449.     break;
  450.     default:
  451.         // assert(0);
  452.     break;
  453.     }
  454.  
  455.     // "II. ROLL FOR DROW, WITCH, OR GHOST MAGIC SPELLS (IF APPLICABLE)."
  456.  
  457.     if (defendtype == MONSTER)
  458.     {   switch (monster[defender].species)
  459.         {
  460.         case GHOST:
  461.             decision = d6();
  462.             if (decision <= 3)
  463.             {   cast(defender, decision);
  464.             }
  465.         break;
  466.         case DROW:
  467.             cast(defender, d6());
  468.         break;
  469.         case WITCH:
  470.             cast(defender, d6());
  471.             if (attackersleft())
  472.             {   cast(defender, d6());
  473.             }
  474.         break;
  475.         default:
  476.         break;
  477.     }   }
  478.  
  479.     if (!attackersleft())
  480.     {   // no attackers, abort combat
  481.         deselect_combatants(attackhero, defendtype, defendhero, defender);
  482.         return;
  483.     }
  484.  
  485.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  486.     {   if (hero[whichhero].attacking)
  487.         {   attackstrength += hero[whichhero].strength;
  488.         } elif (hero[whichhero].defending)
  489.         {   defendstrength += hero[whichhero].strength;
  490.     }   }
  491.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  492.     {   if (jarl[whichjarl].attacking)
  493.         {   attackstrength += jarl[whichjarl].strength;
  494.         } elif (jarl[whichjarl].defending)
  495.         {   defendstrength += jarl[whichjarl].strength;
  496.     }   }
  497.  
  498.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  499.     {   if (hero[whichhero].attacking && hero[whichhero].hagall)
  500.         {   attackstrength--;
  501.         } elif (hero[whichhero].defending && hero[whichhero].hagall)
  502.         {   defendstrength--;
  503.     }   }
  504.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  505.     {   if (jarl[whichjarl].attacking && jarl[whichjarl].hagall)
  506.         {   attackstrength--;
  507.         } elif (jarl[whichjarl].defending && jarl[whichjarl].hagall)
  508.         {   defendstrength--;
  509.     }   }
  510.     if (defendtype == MONSTER && monster[defender].hagall)
  511.     {   defendstrength--;
  512.     }
  513.  
  514.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  515.     {   if (hero[whichhero].alive && hero[whichhero].rune == OGAL)
  516.         {   if (hero[whichhero].attacking)
  517.             {   attackstrength++;
  518.             } elif (hero[whichhero].defending)
  519.             {   defendstrength++;
  520.     }   }   }
  521.  
  522.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  523.     {   if
  524.         (   (   sord[whichsord].possessortype == HERO
  525.              && hero[sord[whichsord].possessor].attacking
  526.             )
  527.          || (   sord[whichsord].possessortype == JARL
  528.              && jarl[sord[whichsord].possessor].attacking
  529.         )   )
  530.         {   if (whichsord == BALMUNG || whichsord == HRUNTING)
  531.             {   attackstrength++;
  532.             } elif (whichsord == DRAGVENDILL || whichsord == GRAM || whichsord == TYRFING)
  533.             {   attackstrength += 2;
  534.             } elif (whichsord == LOVI)
  535.             {   attackstrength++;
  536.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  537.                 {   if (jarl[whichjarl].defending)
  538.                     {   attackstrength += 2;
  539.                         break;
  540.         }   }   }   }
  541.         elif
  542.         (   (   sord[whichsord].possessortype == HERO
  543.              && hero[sord[whichsord].possessor].defending
  544.             )
  545.          || (   sord[whichsord].possessortype == JARL
  546.              && jarl[sord[whichsord].possessor].defending
  547.         )   )
  548.         {   if (whichsord == BALMUNG || whichsord == HRUNTING)
  549.             {   defendstrength++;
  550.             } elif (whichsord == DRAGVENDILL || whichsord == GRAM || whichsord == TYRFING)
  551.             {   defendstrength += 2;
  552.             } elif (whichsord == LOVI)
  553.             {   defendstrength++;
  554.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  555.                 {   if (jarl[whichjarl].attacking)
  556.                     {   defendstrength += 2;
  557.                         break;
  558.     }   }   }   }   }
  559.  
  560.     /* "III. MODIFY THE DIE ROLL WITH LUCK. Before the die is rolled,
  561.     heroes who are involved in the battle (or who have jarls involved in
  562.     the battle) may modify the die roll up or down one with each point of
  563.     luck expended before the die is rolled. If there are two or more
  564.     heroes involved in the battle they should each write how much luck
  565.     they are using to modify the die roll and how before revealing the
  566.     amounts simultaneously." */
  567.  
  568.     if (hero[attackhero].control == HUMAN)
  569.     {   if (hero[attackhero].luck >= 1)
  570.         {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKING, "Attacking"));
  571.             saywho(HERO, attackhero, FALSE, TRUE);
  572.             strcat(saystring, ", ");
  573.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USE_LUCK, "use luck"));
  574.             strcat(saystring, " (0-");
  575.             if (hero[attackhero].luck >= 9)
  576.             {   strcat(saystring, "9");
  577.             } else
  578.             {   stcl_d(numberstring, hero[attackhero].luck);
  579.                 strcat(saystring, numberstring);
  580.             }
  581.             strcat(saystring, ")?");
  582.             say(LOWER);
  583.             attackluck = getluck(attackhero);
  584.     }   }
  585.     else
  586.     {   // assert(hero[attackhero].control == AMIGA);
  587.         if (attackstrength < defendstrength && hero[attackhero].luck > 1)
  588.         {   attackluck = defendstrength - attackstrength;
  589.             if (attackluck > hero[attackhero].luck - 1)
  590.             {   attackluck = hero[attackhero].luck - 1;
  591.             }
  592.             hero[attackhero].luck -= attackluck;
  593.  
  594.             strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKING, "Attacking"));
  595.             saywho(HERO, attackhero, FALSE, FALSE);
  596.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USED, "used"));
  597.             strcat(saystring, " ");
  598.             stcl_d(numberstring, attackluck);
  599.             strcat(saystring, numberstring);
  600.             strcat(saystring, " ");
  601.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LUCK2, "luck"));
  602.             strcat(saystring, ".");
  603.             say(LOWER);
  604.             anykey();
  605.     }   }
  606.  
  607.     if (defendhero != -1)
  608.     {   if (hero[defendhero].control == HUMAN)
  609.         {   if (hero[defendhero].luck >= 1)
  610.             {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEFENDING, "Defending"));
  611.                 saywho(defendtype, defender, FALSE, TRUE);
  612.                 strcat(saystring, ", ");
  613.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USE_LUCK, "use luck"));
  614.                 strcat(saystring, " (0-");
  615.                 if (hero[defendhero].luck >= 9)
  616.                 {   strcat(saystring, "9");
  617.                 } else
  618.                 {   stcl_d(numberstring, hero[defendhero].luck);
  619.                     strcat(saystring, numberstring);
  620.                 }
  621.                 strcat(saystring, ")?");
  622.                 say(LOWER);
  623.                 defendluck = getluck(defendhero);
  624.         }   }
  625.         else
  626.         {   // assert(hero[defendhero].control == AMIGA);
  627.             if (defendstrength < attackstrength && hero[defendhero].luck > 1)
  628.             {   defendluck = attackstrength - defendstrength;
  629.                 if (defendluck > hero[defendhero].luck - 1)
  630.                 {   defendluck = hero[defendhero].luck - 1;
  631.                 }
  632.                 hero[defendhero].luck -= defendluck;
  633.                 strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEFENDING, "Defending"));
  634.                 saywho(HERO, defendhero, FALSE, FALSE);
  635.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USED, "used"));
  636.                 strcat(saystring, " ");
  637.                 stcl_d(numberstring, defendluck);
  638.                 strcat(saystring, numberstring);
  639.                 strcat(saystring, " ");
  640.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LUCK2, "luck"));
  641.                 strcat(saystring, ".");
  642.                 say(LOWER);
  643.                 anykey();
  644.     }   }   }
  645.  
  646.     attackstrength += attackluck;
  647.     defendstrength += defendluck;
  648.  
  649.     if (hero[attackhero].attacking)
  650.     {   attackstrength += odin_tyr(attackhero, TRUE);
  651.         if (attackstrength < 0)
  652.         {   attackstrength = 0;
  653.     }   }
  654.     if (defendhero != -1 && hero[defendhero].defending)
  655.     {   defendstrength += odin_tyr(defendhero, FALSE);
  656.         if (defendstrength < 0)
  657.         {   defendstrength = 0;
  658.     }   }
  659.  
  660.     if
  661.     (   (   sord[BALMUNG].possessortype == HERO
  662.          && hero[sord[BALMUNG].possessor].attacking
  663.         )
  664.      || (   sord[BALMUNG].possessortype == JARL
  665.          && jarl[sord[BALMUNG].possessor].attacking
  666.     )   )
  667.     {   ; // one of the attackers is wielding Balmung
  668.         // assert(sord[BALMUNG].where == -1);
  669.     } else
  670.     {   if
  671.         (   (   treasure[MAGICSHIRT].possessortype == HERO
  672.              && hero[treasure[MAGICSHIRT].possessor].defending
  673.             )
  674.          || (   treasure[MAGICSHIRT].possessortype == JARL
  675.              && jarl[treasure[MAGICSHIRT].possessor].defending
  676.         )   )
  677.         {   // one of the defenders is wearing the Magic Shirt
  678.             // assert(treasure[MAGICSHIRT].where == -1);
  679.  
  680.             defendstrength++;
  681.         }
  682.  
  683.         if
  684.         (   (   treasure[MAILCOAT].possessortype == HERO
  685.              && hero[treasure[MAILCOAT].possessor].defending
  686.             )
  687.          || (   treasure[MAILCOAT].possessortype == JARL
  688.              && jarl[treasure[MAILCOAT].possessor].defending
  689.         )   )
  690.         {   // one of the defenders is wearing the Mail Coat
  691.             // assert(treasure[MAILCOAT].where == -1);
  692.  
  693.             defendstrength += 2;
  694.     }   }
  695.  
  696.     /* "V. ROLL ONE DIE AND CHECK THE COMBAT RESULTS TABLE TO DETERMINE
  697.     THE OUTCOME OF THE BATTLE AFTER ADDING ALL MODIFIERS TO THE DIE ROLL.
  698.     After all modifications to the combat strengths of both sides have
  699.     been made, subtract the defender's strength from the attacker's and
  700.     consult the COMBAT RESULTS TABLE...to determine the results
  701.     according to a die roll and modifications due to luck." */
  702.  
  703. #ifdef EXTRAVERBOSE
  704. Printf("Involved in this combat are:\n");
  705. Printf(" Attackers:\n");
  706. for (whichhero = 0; whichhero <= HEROES; whichhero++)
  707. {   if (hero[whichhero].attacking)
  708.     {   Printf("  Hero %s!\n", hero[attackhero].name);
  709. }   }
  710. for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  711. {   if (jarl[whichjarl].attacking)
  712.     {   Printf("  Jarl %s!\n", jarl[whichjarl].name);
  713. }   }
  714. Printf(" Defenders:\n");
  715. if (defendhero != -1)
  716. {   if (hero[defendhero].defending)
  717.     {   Printf("  Hero %s!\n", hero[defendhero].name);
  718. }   }
  719. for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  720. {   if (jarl[whichjarl].defending)
  721.     {   Printf("  Jarl %s!\n", jarl[whichjarl].name);
  722. }   }
  723. if (defendhero == -1)
  724. {   if (defendtype == KINGDOM)
  725.     {   Printf("  Kingdom %s!\n", world[defender].name);
  726.     } elif (defendtype == MONSTER)
  727.     {   Printf("  %s %s!\n", monstertypes[monster[defender].species], monster[defender].name);
  728. }   }
  729. #endif
  730.  
  731.     result = d6();
  732.     sprintf
  733.     (   saystring, "%s: %ld. %s: %ld. %s: %ld. ",
  734.         GetCatalogStr(li.li_Catalog, MSG_ATTACKERS, "Attackers"),
  735.         attackstrength,
  736.         GetCatalogStr(li.li_Catalog, MSG_DEFENDERS, "Defenders"),
  737.         defendstrength,
  738.         GetCatalogStr(li.li_Catalog, MSG_ROLL     , "Roll"     ),
  739.         result
  740.     );
  741.     result += attackstrength - defendstrength;
  742.     if (result <= 2)
  743.     {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKERS_KILLED,  "Attackers killed" ));
  744.     } elif (result == 3)
  745.     {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKERS_WOUNDED, "Attackers wounded"));
  746.     } elif (result == 4)
  747.     {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKERS_FLEE,    "Attackers flee"   ));
  748.     } elif (result == 5)
  749.     {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_NO_RESULT,         "No result"        ));
  750.     } elif (result == 6)
  751.     {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_DEFENDERS_FLEE,    "Defenders flee"   ));
  752.     } elif (result == 7)
  753.     {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_DEFENDERS_WOUNDED, "Defenders wounded"));
  754.     } else
  755.     {   // assert(result >= 8);
  756.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_DEFENDERS_KILLED,  "Defenders killed" ));
  757.     }
  758.     strcat(saystring, ".");
  759.  
  760.     say(LOWER);
  761.     anykey();
  762.  
  763.     if (result == 4) // attacker flees
  764.     {   if (sord[HRUNTING].possessortype == HERO)
  765.         {   if (hero[sord[HRUNTING].possessor].attacking)
  766.             {   result = 6; // defender flees
  767.         }   }
  768.         elif (sord[HRUNTING].possessortype == JARL)
  769.         {   if (jarl[sord[HRUNTING].possessor].attacking)
  770.             {   result = 6; // defender flees
  771.     }   }   }
  772.     elif (result == 6) // defender flees
  773.     {   if (sord[HRUNTING].possessortype == HERO)
  774.         {   if (hero[sord[HRUNTING].possessor].defending)
  775.             {   result = 4; // attacker flees
  776.         }   }
  777.         elif (sord[HRUNTING].possessortype == JARL)
  778.         {   if (jarl[sord[HRUNTING].possessor].defending)
  779.             {   result = 4; // attacker flees
  780.     }   }   }
  781.  
  782.     /* "VI. APPLY THE COMBAT RESULT." */
  783.  
  784.     if (hero[attackhero].attacking)
  785.     {   attacktype = HERO;
  786.         attacker   = attackhero;
  787.     } else
  788.     {   attacktype = JARL; // uses the first jarl found
  789.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  790.         {   if (jarl[whichjarl].attacking)
  791.             {   attacker = whichjarl;
  792.                 break;
  793.     }   }   }
  794.  
  795.     if (result <= 2) // attackers killed
  796.     {   if (hero[attackhero].attacking)
  797.         {   kill(defendtype, defender, defendhero, HERO, attackhero, attackhero);
  798.         }
  799.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  800.         {   if (jarl[whichjarl].attacking)
  801.             {   kill(defendtype, defender, defendhero, JARL, whichjarl, attackhero);
  802.     }   }   }
  803.     elif (result == 3) // attackers wounded
  804.     {   if (hero[attackhero].attacking)
  805.         {   wound(defendtype, defender, defendhero, HERO, attackhero, attackhero);
  806.         }
  807.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  808.         {   if (jarl[whichjarl].attacking)
  809.             {   wound(defendtype, defender, defendhero, JARL, whichjarl, attackhero);
  810.     }   }   }
  811.     elif (result == 4) // attackers flee
  812.     {   if (hero[attackhero].attacking)
  813.         {   flee(defendtype, defender, defendhero, HERO, attackhero, attackhero);
  814.         }
  815.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  816.         {   if (jarl[whichjarl].attacking)
  817.             {   flee(defendtype, defender, defendhero, JARL, whichjarl, attackhero);
  818.     }   }   }
  819.     elif (result == 5) // no result
  820.     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_NO_RESULT, "No result"));
  821.         strcat(saystring, ".");
  822.         say(LOWER);
  823.         anykey();
  824.     } elif (result == 6) // defenders flee
  825.     {   if (defendtype == MONSTER || defendtype == KINGDOM)
  826.         {   flee(attacktype, attacker, attackhero, defendtype, defender, -1);
  827.         } else
  828.         {   // assert(defendtype == HERO || defendtype == JARL);
  829.             if (defendhero != -1 && hero[defendhero].defending)
  830.             {   flee(attacktype, attacker, attackhero, HERO, defendhero, defendhero);
  831.             }
  832.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  833.             {   if (jarl[whichjarl].defending)
  834.                 {   flee(attacktype, attacker, attackhero, JARL, whichjarl, defendhero);
  835.     }   }   }   }
  836.     elif (result == 7) // defenders wounded
  837.     {   if (defendtype == MONSTER || defendtype == KINGDOM)
  838.         {   wound(attacktype, attacker, attackhero, defendtype, defender, -1);
  839.         } else
  840.         {   // assert(defendtype == HERO || defendtype == JARL);
  841.             if (defendhero != -1 && hero[defendhero].defending)
  842.             {   wound(attacktype, attacker, attackhero, HERO, defendhero, defendhero);
  843.             }
  844.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  845.             {   if (jarl[whichjarl].defending)
  846.                 {   wound(attacktype, attacker, attackhero, JARL, whichjarl, defendhero);
  847.     }   }   }   }
  848.     else // defenders killed
  849.     {   // assert(result >= 8);
  850.         if (defendtype == MONSTER || defendtype == KINGDOM)
  851.         {   kill(attacktype, attacker, attackhero, defendtype, defender, -1);
  852.         } else
  853.         {   // assert(defendtype == HERO || defendtype == JARL);
  854.             if (defendhero != -1 && hero[defendhero].defending)
  855.             {   kill(attacktype, attacker, attackhero, HERO, defendhero, defendhero);
  856.             }
  857.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  858.             {   if (jarl[whichjarl].defending)
  859.                 {   kill(attacktype, attacker, attackhero, JARL, whichjarl, defendhero);
  860.     }   }   }   }
  861.  
  862.     if (hero[attackhero].attacking)
  863.     {   thor(attackhero);
  864.     }
  865.     if (defendhero != -1 && hero[defendhero].defending && hero[defendhero].alive)
  866.     {   thor(defendhero);
  867.     }
  868.  
  869.     if (hero[attackhero].attacking)
  870.     {   pray(attackhero);
  871.     }
  872.     if (defendhero != -1 && hero[defendhero].defending && hero[defendhero].alive)
  873.     {   pray(defendhero);
  874.     }
  875.  
  876.     deselect_combatants(attackhero, defendtype, defendhero, defender);
  877. }
  878.  
  879. MODULE void flee(SLONG routertype, SLONG router, SLONG routerhero, SLONG routedtype, SLONG routed, SLONG routedhero)
  880. {   if (routedtype == HERO)
  881.     {   hero[routed].glory -= 2;
  882.         if (hero[routed].glory < 0)
  883.         {   hero[routed].glory = 0;
  884.     }   }
  885.  
  886.     if
  887.     (   routertype == HERO
  888.      && routedtype == JARL
  889.     )
  890.     {   if (recruit(routed, routerhero))
  891.         {   return;
  892.     }   }
  893.     elif (routedtype == KINGDOM)
  894.     {   conquer(routertype, router, routerhero, routed);
  895.         return;
  896.     }
  897.  
  898.     saywho(routedtype, routed, FALSE, FALSE);
  899.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
  900.     strcat(saystring, "!");
  901.     say(LOWER);
  902.     anykey();
  903.  
  904.     if
  905.     (   (routertype == HERO && hero[router].control == AMIGA)
  906.      || (routertype == JARL && (jarl[router].hero == -1 || hero[jarl[router].hero].control == AMIGA))
  907.      ||  routertype == MONSTER
  908.      ||  routertype == KINGDOM
  909.     )
  910.     {   amiga_rout(routedtype, routed);
  911.     } else
  912.     {   human_rout(routedtype, routed, routerhero);
  913. }   }
  914.  
  915. MODULE void wound(SLONG woundertype, SLONG wounder, SLONG wounderhero, SLONG woundedtype, SLONG wounded, SLONG woundedhero)
  916. {   SLONG glory = 0,
  917.           luck  = 0;
  918.  
  919.     /* WOUNDED. Heroes on the wounded side are wounded.
  920.     Jarls on the wounded side are removed from the board and placed,
  921.     upside down, in their respective piles, from which they will reenter
  922.     play normally. There is no further effect from being wounded, except
  923.     that jarls that reenter play after being wounded are to be considered
  924.     unrecruited jarls. */
  925.  
  926.     if
  927.     (   woundertype == HERO
  928.      && woundedtype == JARL
  929.     )
  930.     {   if (recruit(wounded, wounderhero))
  931.         {   return;
  932.     }   }
  933.     elif (woundedtype == HERO && hero[wounded].wounded)
  934.     {   kill(woundertype, wounder, wounderhero, woundedtype, wounded, woundedhero);
  935.         return;
  936.     } elif (woundedtype == KINGDOM)
  937.     {   conquer(woundertype, wounder, wounderhero, wounded);
  938.         return;
  939.     }
  940.  
  941.     saywho(woundedtype, wounded, FALSE, FALSE);
  942.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_WOUNDED, "is wounded"));
  943.     strcat(saystring, "!");
  944.     say(LOWER);
  945.     anykey();
  946.  
  947.     if (woundedtype == HERO)
  948.     {   if (hero[wounded].maidens)
  949.         {   hero[wounded].maidens--;
  950.             hero[wounded].wounded = FALSE;
  951.  
  952.             sprintf
  953.             (   saystring,
  954.                 "Frey %s %s%s.",
  955.                 GetCatalogStr(li.li_Catalog, MSG_SENDS_A_MAIDEN_TO_HEAL_HERO, "Frey sends a maiden to heal hero"),
  956.                 hero[wounded].name,
  957.                 GetCatalogStr(li.li_Catalog, MSG_S_WOUND, "'s wound")
  958.             );
  959.             say(LOWER);
  960.             anykey();
  961.         } else hero[wounded].wounded = TRUE;
  962.  
  963.         if (wounderhero != -1)
  964.         {   gain(wounderhero, hero[woundedhero].strength / 2 / 2, hero[woundedhero].strength / 2 / 2);
  965.     }   }
  966.     elif (woundedtype == JARL)
  967.     {   jarl[wounded].alive  = FALSE;
  968.         jarl[wounded].taken  = FALSE;
  969.         jarl[wounded].hero   = -1;
  970.         jarl[wounded].wealth = 0; // this is actually an ambiguity in the rules
  971.         remove_jarl(wounded, TRUE);
  972.  
  973.         drop(JARL, wounded, jarl[wounded].where); // should really be done before anykey()
  974.  
  975.         if (wounderhero != -1)
  976.         {   gain(wounderhero, jarl[wounded].strength / 2 / 2, jarl[wounded].strength / 2 / 2); // not the same as / 4 due to rounding
  977.     }   }
  978.     elif (woundedtype == MONSTER)
  979.     {   monster[wounded].alive = FALSE;
  980.         monster[wounded].taken = FALSE;
  981.         remove_monster(wounded, TRUE);
  982.  
  983.         switch (monster[wounded].species)
  984.         {
  985.         case DRAGON:
  986.             glory = 6;
  987.             luck  = 5;
  988.         break;
  989.         case DROW:
  990.             glory = 3;
  991.             luck  = 2;
  992.         break;
  993.         case GHOST:
  994.             glory = 2;
  995.             luck  = 2;
  996.         break;
  997.         case GIANT:
  998.             glory = 4;
  999.             luck  = 3;
  1000.         break;
  1001.         case TROLL:
  1002.             glory = 3;
  1003.             luck  = 3;
  1004.         break;
  1005.         case WITCH:
  1006.             glory = 5;
  1007.             luck  = 4;
  1008.         break;
  1009.         case HYDRA:
  1010.         case SERPENT:
  1011.             glory = 7;
  1012.             luck  = 5;
  1013.         default:
  1014.             // assert(0);
  1015.         break;
  1016.         }
  1017.         glory /= 2;
  1018.         luck  /= 2;
  1019.  
  1020.         // assert(wounderhero != -1);
  1021.         gain(wounderhero, glory, luck);
  1022. }   }
  1023.  
  1024. MODULE void kill(SLONG killertype, SLONG killer, SLONG killerhero, SLONG killedtype, SLONG killed, SLONG killedhero)
  1025. {   SLONG glory = 0, luck = 0, result, whichjarl;
  1026.  
  1027.     if (killedtype == HERO)
  1028.     {   hero[killed].alive     =
  1029.         hero[killed].attacking =
  1030.         hero[killed].defending = FALSE;
  1031.         remove_hero(killed, TRUE);
  1032.  
  1033.         drop(HERO, killed, hero[killed].where);
  1034.  
  1035.         saywho(HERO, killed, FALSE, FALSE);
  1036.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_KILLED, "is killed"));
  1037.         strcat(saystring, "!");
  1038.         say(LOWER);
  1039.         anykey();
  1040.  
  1041.         if (killerhero != -1)
  1042.         {   gain(killerhero, hero[killedhero].strength / 2, hero[killedhero].strength / 2);
  1043.     }   }
  1044.     elif (killedtype == JARL)
  1045.     {   if
  1046.         (   killerhero == -1
  1047.          || hero[killerhero].where != jarl[killed].where
  1048.          || !recruit(killed, killerhero)
  1049.         )
  1050.         {   jarl[killed].alive     =
  1051.             jarl[killed].attacking =
  1052.             jarl[killed].defending = FALSE;
  1053.             remove_jarl(killed, TRUE);
  1054.  
  1055.             drop(JARL, killed, jarl[killed].where);
  1056.  
  1057.             saywho(JARL, killed, FALSE, FALSE);
  1058.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_KILLED, "is killed"));
  1059.             strcat(saystring, "!");
  1060.             say(LOWER);
  1061.             anykey();
  1062.  
  1063.             if (killerhero != -1 && killedtype == JARL)
  1064.             {   if (hero[killerhero].where == jarl[killed].where)
  1065.                 {   if (jarl[killed].wealth)
  1066.                     {   hero[killerhero].wealth += jarl[killed].wealth;
  1067.                         saywho(HERO, killerhero, FALSE, FALSE);
  1068.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES, "takes"));
  1069.                         strcat(saystring, " ");
  1070.                         stcl_d(numberstring, jarl[killed].wealth);
  1071.                         strcat(saystring, numberstring);
  1072.                         strcat(saystring, " ");
  1073.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
  1074.                         strcat(saystring, " ");
  1075.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FROM, "from"));
  1076.                         strcat(saystring, " ");
  1077.                         saywho(JARL, killed, FALSE, TRUE);
  1078.                         strcat(saystring, ".");
  1079.                         say(LOWER);
  1080.                         anykey();
  1081.                 }   }
  1082.                 else
  1083.                 {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1084.                     {   if
  1085.                         (   jarl[whichjarl].alive
  1086.                          && jarl[whichjarl].hero == killerhero
  1087.                          && jarl[whichjarl].where == jarl[killed].where
  1088.                         )
  1089.                         {   // assert(whichjarl != killed);
  1090.  
  1091.                             if (jarl[killed].wealth)
  1092.                             {   jarl[whichjarl].wealth += jarl[killed].wealth;
  1093.                                 saywho(JARL, whichjarl, FALSE, FALSE);
  1094.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES, "takes"));
  1095.                                 strcat(saystring, " ");
  1096.                                 stcl_d(numberstring, jarl[killed].wealth);
  1097.                                 strcat(saystring, " ");
  1098.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
  1099.                                 strcat(saystring, " ");
  1100.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FROM, "from"));
  1101.                                 strcat(saystring, " ");
  1102.                                 saywho(JARL, killed, FALSE, TRUE);
  1103.                                 strcat(saystring, ".");
  1104.                                 say(LOWER);
  1105.                                 anykey();
  1106.             }   }   }   }   }
  1107.  
  1108.             if (killedhero != -1)
  1109.             {   if (hero[killedhero].control == HUMAN)
  1110.                 {   saywho(HERO, killedhero, TRUE, FALSE);
  1111.                     sprintf
  1112.                     (   saystring2,
  1113.                         "%s %ld (%s)%s %s %ld (%s)%s?",
  1114.                         GetCatalogStr(li.li_Catalog, MSG_LOSE, "lose"),
  1115.                         jarl[killed].strength / 2,
  1116.                         GetCatalogStr(li.li_Catalog, MSG_CHAR_GLORY, "G"),
  1117.                         GetCatalogStr(li.li_Catalog, MSG_UNCHAR_GLORY, "lory"),
  1118.                         GetCatalogStr(li.li_Catalog, MSG_OR, "or"),
  1119.                         jarl[killed].strength / 2,
  1120.                         GetCatalogStr(li.li_Catalog, MSG_CHAR_LUCK, "L"),
  1121.                         GetCatalogStr(li.li_Catalog, MSG_UNCHAR_LUCK, "uck")
  1122.                     );
  1123.                     strcat(saystring, saystring2);
  1124.                     say(LOWER);
  1125.                     do
  1126.                     {   result = getevent(GLKEYBOARD, NULL);
  1127.                     } while (result != onekey[ONEKEY_GLORY] && result != onekey[ONEKEY_LUCK]);
  1128.                     if (result == onekey[ONEKEY_GLORY])
  1129.                     {   hero[killedhero].glory -= jarl[killed].strength / 2;
  1130.                         if (hero[killedhero].glory < 0)
  1131.                         {   hero[killedhero].glory = 0;
  1132.                     }   }
  1133.                     else
  1134.                     {   // assert(result == onekey[ONEKEY_LUCK]);
  1135.                         hero[killedhero].luck  -= jarl[killed].strength / 2;
  1136.                         if (hero[killedhero].luck < 0)
  1137.                         {   hero[killedhero].luck = 0;
  1138.                 }   }   }
  1139.                 else
  1140.                 {   // assert(hero[killedhero].control == AMIGA);
  1141.                     hero[killedhero].glory -= jarl[killed].strength / 2;
  1142.                     if (hero[killedhero].glory < 0)
  1143.                     {   hero[killedhero].glory = 0;
  1144.             }   }   }
  1145.             if (killerhero != -1)
  1146.             {   gain(killerhero, jarl[killed].strength / 2, jarl[killed].strength / 2);
  1147.     }   }   }
  1148.     elif (killedtype == KINGDOM)
  1149.     {   conquer(killertype, killer, killerhero, killed);
  1150.         return;
  1151.     } elif (killedtype == MONSTER)
  1152.     {   monster[killed].alive = FALSE;
  1153.         remove_monster(killed, TRUE);
  1154.  
  1155.         strcpy(saystring, monstertypes[monster[killed].species]);
  1156.         strcat(saystring, " ");
  1157.         strcat(saystring, monster[killed].name);
  1158.         strcat(saystring, " ");
  1159.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_KILLED, "is killed"));
  1160.         strcat(saystring, "!");
  1161.         say(LOWER);
  1162.         anykey();
  1163.  
  1164.         findtreasure(killertype, killer, killerhero, killed);
  1165.  
  1166.         switch (monster[killed].species)
  1167.         {
  1168.         case DRAGON:
  1169.             glory = 6;
  1170.             luck  = 5;
  1171.         break;
  1172.         case DROW:
  1173.             glory = 3;
  1174.             luck  = 2;
  1175.         break;
  1176.         case GHOST:
  1177.             glory = 2;
  1178.             luck  = 2;
  1179.         break;
  1180.         case GIANT:
  1181.             glory = 4;
  1182.             luck  = 3;
  1183.         break;
  1184.         case TROLL:
  1185.             glory = 3;
  1186.             luck  = 3;
  1187.         break;
  1188.         case WITCH:
  1189.             glory = 5;
  1190.             luck  = 4;
  1191.         break;
  1192.         case HYDRA:
  1193.         case SERPENT:
  1194.             glory = 7;
  1195.             luck  = 5;
  1196.         default:
  1197.             // assert(0);
  1198.         break;
  1199.         }
  1200.         // assert(killerhero != -1);
  1201.         gain(killerhero, glory, luck);
  1202.  
  1203.         // check if hero was present at the combat
  1204.         if
  1205.         (   killerhero != -1
  1206.          && hero[killerhero].attacking
  1207.         )
  1208.         {   if
  1209.             (   (   monster[killed].species == DROW
  1210.                  || monster[killed].species == GHOST
  1211.                  || monster[killed].species == WITCH
  1212.                 )
  1213.              && hero[killer].rune == -1
  1214.             )
  1215.             {   hero[killer].rune = rand() % (RUNES + 1);
  1216.                 saywho(HERO, killer, FALSE, FALSE);
  1217.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LEARNS_THE_RUNE, "learns the rune"));
  1218.                 strcat(saystring, " ");
  1219.                 strcat(saystring, rune[hero[killer].rune].name);
  1220.                 strcat(saystring, ", ");
  1221.                 strcat(saystring, rune[hero[killer].rune].desc);
  1222.                 strcat(saystring, ".");
  1223.                 say(LOWER);
  1224.                 anykey();
  1225. }   }   }   }
  1226.  
  1227. MODULE FLAG recruit(SLONG recruited, SLONG recruiterhero)
  1228. {   SLONG result;
  1229.  
  1230.     if
  1231.     (   jarl[recruited].hero == -1
  1232.      && hero[recruiterhero].luck >= 1
  1233.      && jarl[recruited].recruitable
  1234.     )
  1235.     {   jarl[recruited].recruitable = FALSE;
  1236.         if (countjarls(recruiterhero) < 4)
  1237.         {   if (hero[recruiterhero].control == HUMAN)
  1238.             {   saywho(HERO, recruiterhero, TRUE, FALSE);
  1239.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RECRUIT_JARL, "recruit jarl"));
  1240.                 strcat(saystring, " ");
  1241.                 strcat(saystring, jarl[recruited].name);
  1242.                 strcat(saystring, " (");
  1243.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
  1244.                 strcat(saystring, "/");
  1245.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
  1246.                 strcat(saystring, ")?");
  1247.                 say(LOWER);
  1248.                 do
  1249.                 {   result = getevent(YNKEYBOARD, NULL);
  1250.                 } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  1251.                 if (result == onekey[ONEKEY_YES])
  1252.                 {   hero[recruiterhero].luck--;
  1253.                     gain(recruiterhero, jarl[recruited].strength / 2, jarl[recruited].strength / 2);
  1254.                     jarl[recruited].hero = recruiterhero;
  1255.                     return(TRUE);
  1256.                 } else
  1257.                 {   // assert(result == onekey[ONEKEY_NO]);
  1258.             }   }
  1259.             else
  1260.             {   // assert(hero[recruiterhero].control == AMIGA);
  1261.                 hero[recruiterhero].luck--;
  1262.                 gain(recruiterhero, jarl[recruited].strength / 2, jarl[recruited].strength / 2);
  1263.                 jarl[recruited].hero = recruiterhero;
  1264.  
  1265.                 saywho(HERO, recruiterhero, FALSE, FALSE);
  1266.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RECRUITS_JARL, "recruits jarl"));
  1267.                 strcat(saystring, " ");
  1268.                 strcat(saystring, jarl[recruited].name);
  1269.                 strcat(saystring, ".");
  1270.                 say(LOWER);
  1271.                 anykey();
  1272.  
  1273.                 return(TRUE);
  1274.     }   }   }
  1275.  
  1276.     return(FALSE);
  1277. }
  1278.  
  1279. MODULE SLONG d6(void)
  1280. {   return((rand() % 6) + 1);
  1281. }
  1282. AGLOBAL void newhero(SLONG whichhero, FLAG givesord)
  1283. {   SLONG whichjarl, whichsord;
  1284.  
  1285.     hero[whichhero].where     =
  1286.     hero[whichhero].homewhere = rand() % 36;
  1287.     hero[whichhero].glory     =
  1288.     hero[whichhero].wealth    = 0;
  1289.     hero[whichhero].luck      = 3;
  1290.     hero[whichhero].alive     = TRUE;
  1291.     hero[whichhero].verydead  =
  1292.     hero[whichhero].wounded   =
  1293.     hero[whichhero].hagall    =
  1294.     hero[whichhero].attacking =
  1295.     hero[whichhero].defending =
  1296.     hero[whichhero].loseturn  = FALSE;
  1297.     hero[whichhero].rune      =
  1298.     hero[whichhero].god       = -1;
  1299.     hero[whichhero].sea       = NORMAL;
  1300.     hero[whichhero].maidens   = 0;
  1301.     if (givesord)
  1302.     {   hero[whichhero].promoted = -1;
  1303.     }
  1304.  
  1305.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1306.     {   if (jarl[whichjarl].hero == whichhero)
  1307.         {   jarl[whichjarl].hero = -1;
  1308.     }   }
  1309.  
  1310.     deselect_hero(whichhero, FALSE);
  1311.     move_hero(whichhero, TRUE);
  1312.     // we don't unslot newborn counters
  1313.  
  1314.     if (!givesord)
  1315.     {   return;
  1316.     }
  1317.  
  1318.     // at least one sword should should always be available
  1319.     do
  1320.     {   whichsord = rand() % 6;
  1321.     } while (sord[whichsord].taken);
  1322.     sord[whichsord].taken         = TRUE;
  1323.     sord[whichsord].possessortype = HERO;
  1324.     sord[whichsord].possessor     = whichhero;
  1325.     sord[whichsord].where         = -1;
  1326.  
  1327.     sprintf
  1328.     (   saystring,
  1329.         "%s %s %s.",
  1330.         hero[whichhero].name,
  1331.         GetCatalogStr(li.li_Catalog, MSG_HAS_THE_SWORD, "has the sword"),
  1332.         sord[whichsord].name
  1333.     );
  1334.     say(LOWER);
  1335.     anykey();
  1336. }
  1337. AGLOBAL void showcountry(SLONG country)
  1338. {   if (country >= 0 && country <= 65)
  1339.     {   strcpy(saystring, world[country].name);
  1340.         if (country <= 35)
  1341.         {   strcat(saystring, " (");
  1342.             stcl_d(numberstring, world[country].tax);
  1343.             strcat(saystring, numberstring);
  1344.             strcat(saystring, ")");
  1345.     }   }
  1346.     else
  1347.     {   strcpy(saystring, "-");
  1348.     }
  1349.     say(UPPER);
  1350. }
  1351.  
  1352. MODULE void attack(SLONG whichhero)
  1353. {   SLONG attackers,
  1354.           countertype    = -1,
  1355.           country,
  1356.           totalstrength,
  1357.           weakestmonster = -1, // to avoid spurious compiler warnings
  1358.           weakeststrength,
  1359.           whichattack,
  1360.           whichcountry,
  1361.           whichjarl,
  1362.           whichmonster,
  1363.           whichmonster2,
  1364.           whichrivalhero;
  1365.     FLAG  must        = FALSE;
  1366.  
  1367.     if (hero[whichhero].alive)
  1368.     {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  1369.         {   hero[whichhero].attacked[whichattack]   = -1;
  1370.             hero[whichhero].attacktype[whichattack] = -1;
  1371.         }
  1372.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1373.         {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  1374.             {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  1375.                 {   jarl[whichjarl].attacked[whichattack]   = -1;
  1376.                     jarl[whichjarl].attacktype[whichattack] = -1;
  1377.         }   }   }
  1378.  
  1379.         for (whichmonster = 0; whichmonster <= monsters; whichmonster++)
  1380.         {   if (monster[whichmonster].alive && monster[whichmonster].where == hero[whichhero].where)
  1381.             {   must = TRUE;
  1382.                 weakeststrength = 99;
  1383.                 for (whichmonster2 = 0; whichmonster2 <= monsters; whichmonster2++)
  1384.                 {   if (monster[whichmonster2].alive && monster[whichmonster2].where == hero[whichhero].where && monster[whichmonster2].strength < weakeststrength)
  1385.                     {   weakeststrength = monster[whichmonster2].strength;
  1386.                         weakestmonster  = whichmonster2;
  1387.                 }   }
  1388.                 break;
  1389.         }   }
  1390.  
  1391.         if (hero[whichhero].control == HUMAN)
  1392.         {   while(autosense(whichhero))
  1393.             {   saywho(HERO, whichhero, TRUE, FALSE);
  1394.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SELECT_ATTACKERS, "select attackers"));
  1395.                 strcat(saystring, "?");
  1396.                 say(LOWER);
  1397.                 hint
  1398.                 (   (STRPTR) GetCatalogStr(li.li_Catalog, MSG_SELECT, "Select"),
  1399.                     (STRPTR) GetCatalogStr(li.li_Catalog, MSG_CANCEL, "Cancel")
  1400.                 );
  1401.                 country = getevent(COUNTRY, &countertype);
  1402.  
  1403.                 if (country >= 0)
  1404.                 {   if (hero[whichhero].alive && hero[whichhero].where == country && !hero[whichhero].routed)
  1405.                     {   attackers = 1;
  1406.                         select_hero(whichhero, FALSE);
  1407.                         hero[whichhero].attacking = TRUE;
  1408.                     } else
  1409.                     {   attackers = 0;
  1410.                     }
  1411.                     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1412.                     {   if (jarl[whichjarl].alive && jarl[whichjarl].where == country && jarl[whichjarl].hero == whichhero && !jarl[whichjarl].routed)
  1413.                         {   attackers++;
  1414.                             select_jarl(whichjarl, FALSE);
  1415.                             jarl[whichjarl].attacking = TRUE;
  1416.                     }   }
  1417.                     if (attackers)
  1418.                     {   refreshcounters();
  1419.                         getdefender(whichhero, country);
  1420.                 }   }
  1421.                 elif (country == -3)
  1422.                 {   if (must && hero[whichhero].alive && !hero[whichhero].routed)
  1423.                     {   // check whether the hero has fought a monster
  1424.                         for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  1425.                         {   if (hero[whichhero].attacktype[whichattack] == MONSTER)
  1426.                             {   return;
  1427.                         }   }
  1428.                         saywho(HERO, whichhero, TRUE, FALSE);
  1429.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_YOU_MUST_FIGHT_A_MONSTER, "you must fight a monster"));
  1430.                         strcat(saystring, ".");
  1431.                         say(LOWER);
  1432.                         anykey();
  1433.                     } else
  1434.                     {   if (hero[whichhero].attacking)
  1435.                         {   deselect_hero(whichhero, FALSE);
  1436.                         }
  1437.                         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1438.                         {   if (jarl[whichjarl].alive && jarl[whichjarl].attacking)
  1439.                             {   deselect_jarl(whichjarl, FALSE);
  1440.                         }   }
  1441.                         refreshcounters();
  1442.                         return;
  1443.         }   }   }   }
  1444.         elif (hero[whichhero].control == AMIGA)
  1445.         {   saywho(HERO, whichhero, FALSE, FALSE);
  1446.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CONSIDERS_ATTACKS, "considers attacks"));
  1447.             strcat(saystring, "...");
  1448.             say(LOWER);
  1449.  
  1450.             for (whichcountry = 0; whichcountry <= 65; whichcountry++)
  1451.             {   // check for possible enemies
  1452.  
  1453.                 if (!(totalstrength = getattackers(whichhero, whichcountry, FALSE)))
  1454.                 {   continue;
  1455.                 }
  1456.                 for (whichrivalhero = 0; whichrivalhero <= HEROES; whichrivalhero++)
  1457.                 {   if
  1458.                     (   whichhero != whichrivalhero
  1459.                      && hero[whichrivalhero].alive
  1460.                      && hero[whichrivalhero].where == whichcountry
  1461.                      && totalstrength > checkdefenders_hero(whichrivalhero, whichcountry) + hero[whichrivalhero].luck
  1462.                     )
  1463.                     {   amiga_attack(whichhero, HERO, whichrivalhero, whichcountry);
  1464.                 }   }
  1465.  
  1466.                 if (!(totalstrength = getattackers(whichhero, whichcountry, FALSE)))
  1467.                 {   continue;
  1468.                 }
  1469.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1470.                 {   if
  1471.                     (   jarl[whichjarl].alive
  1472.                      && jarl[whichjarl].hero != whichhero
  1473.                      && jarl[whichjarl].where == whichcountry
  1474.                      && (   (jarl[whichjarl].face == FACEDOWN && hero[whichhero].luck >= 1)
  1475.                          || totalstrength > checkdefenders_jarl(whichjarl, whichcountry) + 1
  1476.                     )   )
  1477.                     {    amiga_attack(whichhero, JARL, whichjarl, whichcountry);
  1478.                 }   }
  1479.  
  1480.                 if (!(totalstrength = getattackers(whichhero, whichcountry, FALSE)))
  1481.                 {   continue;
  1482.                 }
  1483.                 for (whichmonster = 0; whichmonster <= monsters; whichmonster++)
  1484.                 {   if
  1485.                     (   monster[whichmonster].alive
  1486.                      && monster[whichmonster].where == whichcountry
  1487.                      && (   (must && weakestmonster == whichmonster)
  1488.                          || totalstrength > monster[whichmonster].strength + 1
  1489.                     )   )
  1490.                     {   amiga_attack(whichhero, MONSTER, whichmonster, whichcountry);
  1491.                 }   }
  1492.  
  1493.                 if (!(totalstrength = getattackers(whichhero, whichcountry, FALSE)))
  1494.                 {   continue;
  1495.                 }
  1496.                 if
  1497.  
  1498.                 (   whichcountry <= 35
  1499.                  && world[whichcountry].hero != whichhero
  1500.                  && !world[whichcountry].is
  1501.                  && totalstrength > world[whichcountry].tax + 2
  1502.                 )
  1503.                 {   amiga_attack(whichhero, KINGDOM, whichcountry, whichcountry);
  1504.             }   }
  1505.  
  1506.             deselect_hero(whichhero, FALSE);
  1507.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1508.             {   if (jarl[whichjarl].attacking)
  1509.                 {   deselect_jarl(whichjarl, FALSE);
  1510.             }   }
  1511.             refreshcounters();
  1512. }   }   }
  1513.  
  1514. MODULE void gain(SLONG whichhero, SLONG glory, SLONG luck)
  1515. {   SLONG result;
  1516.  
  1517.     if (glory == 0 && luck == 0)
  1518.     {   return;
  1519.     }
  1520.  
  1521.     if (hero[whichhero].control == HUMAN)
  1522.     {   saywho(HERO, whichhero, TRUE, FALSE);
  1523.         sprintf
  1524.         (   saystring2,
  1525.             "%s %ld (%s)%s %s %ld (%s)%s?",
  1526.             GetCatalogStr(li.li_Catalog, MSG_GAIN,         "gain"),
  1527.             glory,
  1528.             GetCatalogStr(li.li_Catalog, MSG_CHAR_GLORY,   "G"),
  1529.             GetCatalogStr(li.li_Catalog, MSG_UNCHAR_GLORY, "lory"),
  1530.             GetCatalogStr(li.li_Catalog, MSG_OR,           "or"),
  1531.             luck,
  1532.             GetCatalogStr(li.li_Catalog, MSG_CHAR_LUCK,    "L"),
  1533.             GetCatalogStr(li.li_Catalog, MSG_UNCHAR_LUCK,  "uck")
  1534.         );
  1535.         strcat(saystring, saystring2);
  1536.         say(LOWER);
  1537.  
  1538.         do
  1539.         {   result = getevent(GLKEYBOARD, NULL);
  1540.         } while (result != onekey[ONEKEY_GLORY] && result != onekey[ONEKEY_LUCK]);
  1541.         if (result == onekey[ONEKEY_GLORY])
  1542.         {   hero[whichhero].glory += glory;
  1543.         } else
  1544.         {   // assert(result == onekey[ONEKEY_LUCK]);
  1545.             hero[whichhero].luck  += luck;
  1546.     }   }
  1547.     else
  1548.     {   if (rand() % 2)
  1549.         {   hero[whichhero].luck += luck;
  1550.         } else
  1551.         {   hero[whichhero].glory += glory;
  1552. }   }   }
  1553.  
  1554. MODULE void move(SLONG whichhero)
  1555. {   SLONG assessment[CONNECTIONS + 2],
  1556.           bestassessment = 0, // to avoid spurious compiler warnings
  1557.           bestcountry,
  1558.           bestmove,
  1559.           country,
  1560.           i,
  1561.           moves,
  1562.           oldcountry,
  1563.           whichconnection,
  1564.           whichjarl;
  1565.     FLAG  legal;
  1566.  
  1567. // HEROES
  1568.  
  1569.     if (hero[whichhero].alive)
  1570.     {
  1571.  
  1572. #ifdef QUICKMOVES
  1573.         if (hero[whichhero].control == HUMAN)
  1574.         {   select_hero(whichhero, TRUE);
  1575.         }
  1576. #else
  1577.         select_hero(whichhero, TRUE);
  1578. #endif
  1579.  
  1580.         moves = getmoves(HERO, whichhero, FALSE);
  1581.         movearray[0] = hero[whichhero].where;
  1582.         whichrealmove =
  1583.         whichmove     = 1;
  1584.         oldcountry = hero[whichhero].where;
  1585.         freemove   = FALSE;
  1586.  
  1587.         for (i = 0; i <= 65; i++)
  1588.         {   world[i].visited = FALSE;
  1589.         }
  1590.         world[hero[whichhero].where].visited = TRUE;
  1591.  
  1592.         if (moves < 1)
  1593.         {   goto HEROMOVE_END;
  1594.         }
  1595.  
  1596.         if (hero[whichhero].control == HUMAN)
  1597.         {   if
  1598.             (   treasure[FREYFAXI].possessortype == HERO
  1599.              && treasure[FREYFAXI].possessor     == whichhero
  1600.             )
  1601.             {   // assert(treasure[FREYFAXI].where == -1);
  1602.                 // assert(faxirides >= 1);
  1603.  
  1604.                 if (ask_treasure(HERO, whichhero, FREYFAXI))
  1605.                 {   treasure_disappear(FREYFAXI);
  1606.                     moves = getmoves(HERO, whichhero, TRUE);
  1607.             }   }
  1608.  
  1609.             if
  1610.             (   treasure[TELEPORTSCROLL].possessortype == HERO
  1611.              && treasure[TELEPORTSCROLL].possessor     == whichhero
  1612.             )
  1613.             {   // assert(treasure[TELEPORTSCROLL].where == -1);
  1614.  
  1615.                 if (ask_treasure(HERO, whichhero, TELEPORTSCROLL))
  1616.                 {   treasure_disappear(TELEPORTSCROLL);
  1617.  
  1618.                     saywho(HERO, whichhero, TRUE, FALSE);
  1619.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SELECT_DESTINATION, "select destination"));
  1620.                     strcat(saystring, "?");
  1621.                     say(LOWER);
  1622.                     hint
  1623.                     (   (STRPTR) GetCatalogStr(li.li_Catalog, MSG_SELECT, "Select"),
  1624.                         "-"
  1625.                     );
  1626.  
  1627.                     do
  1628.                     {   country = getevent(COUNTRY, NULL);
  1629.                     } while (country < 0 || country > 65);
  1630.                     onemove_hero(whichhero, country);
  1631.                     goto HEROMOVE_CONTINUE;
  1632.             }   }
  1633.  
  1634.             do
  1635.             {   saywho(HERO, whichhero, FALSE, FALSE);
  1636.                 sprintf
  1637.                 (   saystring2,
  1638.                     "%s %s, %s %ld %s %ld?",
  1639.                     GetCatalogStr(li.li_Catalog, MSG_IN,     "in"),
  1640.                     world[hero[whichhero].where].name,
  1641.                     GetCatalogStr(li.li_Catalog, MSG_MOVE,   "move"),
  1642.                     whichmove,
  1643.                     GetCatalogStr(li.li_Catalog, MSG_OF,     "of"),
  1644.                     moves
  1645.                 );
  1646.                 strcat(saystring, saystring2);
  1647.                 say(LOWER);
  1648.                 hint
  1649.                 (   (STRPTR) GetCatalogStr(li.li_Catalog, MSG_MOVE2,  "Move"),
  1650.                     (STRPTR) GetCatalogStr(li.li_Catalog, MSG_FINISH, "Finish")
  1651.                 );
  1652.  
  1653.                 do
  1654.                 {   country = getevent(COUNTRY, NULL);
  1655.                 } while ((country < -3 || country > 65) || country == -1);
  1656.                 if (country == -3)
  1657.                 {   break;
  1658.                 } elif (country == -2)
  1659.                 {   whichmove     =
  1660.                     whichrealmove = 1;
  1661.                     unslot_hero(whichhero);
  1662.                     hero[whichhero].where = oldcountry;
  1663.                     move_hero(whichhero, TRUE);
  1664.                     freemove = FALSE;
  1665.                 } else
  1666.                 {   legal = FALSE;
  1667.                     for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
  1668.                     {   if (world[hero[whichhero].where].connection[whichconnection] == country)
  1669.                         {   legal = TRUE;
  1670.                             break; // for speed
  1671.                     }   }
  1672.                     if (legal && islegal(HERO, whichhero, country, TRUE))
  1673.                     {   onemove_hero(whichhero, country);
  1674.                 }   }
  1675.             } while (whichmove <= moves);
  1676.  
  1677. HEROMOVE_CONTINUE:
  1678.             ;
  1679.  
  1680.         } else
  1681.         {   // assert(hero[whichhero].control == AMIGA);
  1682.  
  1683.             saywho(HERO, whichhero, FALSE, FALSE);
  1684.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_MOVING, "is moving"));
  1685.             strcat(saystring, "...");
  1686.             say(LOWER);
  1687.  
  1688.             if
  1689.             (   hero[whichhero].wounded
  1690.              && (   hero[whichhero].rune == ING
  1691.                  || hero[whichhero].where == hero[whichhero].homewhere
  1692.             )   )
  1693.             {   goto HEROMOVE_END; // rest to heal
  1694.             }
  1695.  
  1696.             do
  1697.             {   assessment[CONNECTIONS + 1] = assess_hero(whichhero, hero[whichhero].where) - 1;
  1698.                 for (i = 0; i <= CONNECTIONS; i++)
  1699.                 {   assessment[i] = assess_hero(whichhero, world[hero[whichhero].where].connection[i]);
  1700.                 }
  1701.                 bestmove = -100;
  1702.                 for (i = 0; i <= CONNECTIONS + 1; i++)
  1703.                 {   if
  1704.                     (    assessment[i] >  bestmove
  1705.                      || (assessment[i] == bestmove && !(rand() % 2))
  1706.                     )
  1707.                     {   bestassessment = i;
  1708.                         bestmove       = assessment[i];
  1709.                 }   }
  1710.                 if (bestassessment == CONNECTIONS + 1)
  1711.                 {   bestcountry = hero[whichhero].where;
  1712.                 } else
  1713.                 {   bestcountry = world[hero[whichhero].where].connection[bestassessment];
  1714.                 }
  1715.                 // assert(bestcountry >= 0 && bestcountry <= 65);
  1716.  
  1717.                 if
  1718.                 (   bestcountry != hero[whichhero].where // if moving
  1719.                  && !(world[bestcountry].visited)
  1720.                  && islegal(HERO, whichhero, bestcountry, FALSE)
  1721.                 )
  1722.                 {   onemove_hero(whichhero, bestcountry);
  1723.                 } else
  1724.                 {   break;
  1725.             }   }
  1726.             while (whichmove <= moves);
  1727.         }
  1728.  
  1729. HEROMOVE_END:
  1730.  
  1731.         /* For humans and Amiga */
  1732.  
  1733.         for (i = 0; i < whichrealmove; i++)
  1734.         {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1735.             {   if (movearray[i] == jarl[whichjarl].where && jarl[whichjarl].hero == whichhero)
  1736.                 {   // hero moved past jarl during move
  1737.                     givegold(whichhero, whichjarl);
  1738.         }   }   }
  1739.  
  1740.         needtreasure(HERO, whichhero, hero[whichhero].where, hero[whichhero].control);
  1741.         needsord(HERO, whichhero, hero[whichhero].where, hero[whichhero].control);
  1742.         brosung(HERO, whichhero, hero[whichhero].control);
  1743.  
  1744.         // check healing
  1745.  
  1746.         if
  1747.         (   whichmove == 1
  1748.          && hero[whichhero].wounded
  1749.          && (   hero[whichhero].where == hero[whichhero].homewhere
  1750.              || hero[whichhero].rune  == ING
  1751.         )   )
  1752.         {   hero[whichhero].wounded = FALSE;
  1753.             saywho(HERO, whichhero, FALSE, FALSE);
  1754.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HEALS, "heals"));
  1755.             strcat(saystring, ".");
  1756.             say(LOWER);
  1757.             anykey();
  1758.         } elif
  1759.         (   treasure[HEALINGPOTION].possessortype == HERO
  1760.          && treasure[HEALINGPOTION].possessor     == whichhero
  1761.          && hero[whichhero].wounded
  1762.         )
  1763.         {   if (ask_treasure(HERO, whichhero, HEALINGPOTION))
  1764.             {   hero[whichhero].wounded = FALSE;
  1765.                 treasure_disappear(HEALINGPOTION);
  1766.         }   }
  1767. #ifdef QUICKMOVES
  1768.         if (hero[whichhero].control == HUMAN)
  1769.         {   deselect_hero(whichhero, TRUE);
  1770.         }
  1771. #else
  1772.         deselect_hero(whichhero, TRUE);
  1773. #endif
  1774.  
  1775.         // JARLS
  1776.  
  1777.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1778.         {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  1779.             {   // note that whichrealmove and freemove are not used for jarls
  1780.  
  1781. #ifdef QUICKMOVES
  1782.                 if (hero[whichhero].control == HUMAN)
  1783.                 {   select_jarl(whichjarl, TRUE);
  1784.                 }
  1785. #else
  1786.                 select_jarl(whichjarl, TRUE);
  1787. #endif
  1788.  
  1789.                 moves = getmoves(JARL, whichjarl, FALSE);
  1790.                 movearray[0] = jarl[whichjarl].where;
  1791.                 whichmove = 1;
  1792.                 oldcountry = jarl[whichjarl].where;
  1793.  
  1794.                 for (i = 0; i <= 65; i++)
  1795.                 {   world[i].visited = FALSE;
  1796.                 }
  1797.                 world[jarl[whichjarl].where].visited = TRUE;
  1798.  
  1799.                 if (moves < 1)
  1800.                 {   goto JARLMOVE_END;
  1801.                 }
  1802.  
  1803.                 if (hero[whichhero].control == HUMAN)
  1804.                 {   if
  1805.                     (   treasure[FREYFAXI].possessortype == JARL
  1806.                      && treasure[FREYFAXI].possessor     == whichjarl
  1807.                     )
  1808.                     {   // assert(treasure[FREYFAXI].where == -1);
  1809.                         // assert(faxirides >= 1);
  1810.  
  1811.                         if (ask_treasure(JARL, whichjarl, FREYFAXI))
  1812.                         {   treasure_disappear(FREYFAXI);
  1813.                             moves = getmoves(JARL, whichjarl, TRUE);
  1814.                     }   }
  1815.  
  1816.                     if
  1817.                     (   treasure[TELEPORTSCROLL].possessortype == JARL
  1818.                      && treasure[TELEPORTSCROLL].possessor     == whichjarl
  1819.                     )
  1820.                     {   // assert(treasure[TELEPORTSCROLL].where == -1);
  1821.  
  1822.                         if (ask_treasure(JARL, whichjarl, TELEPORTSCROLL))
  1823.                         {   treasure_disappear(TELEPORTSCROLL);
  1824.  
  1825.                             saywho(JARL, whichjarl, TRUE, FALSE);
  1826.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SELECT_DESTINATION, "select destination"));
  1827.                             strcat(saystring, "?");
  1828.                             say(LOWER);
  1829.                             hint
  1830.                             (   (STRPTR) GetCatalogStr(li.li_Catalog, MSG_SELECT, "Select"),
  1831.                                 "-"
  1832.                             );
  1833.  
  1834.                             do
  1835.                             {   country = getevent(COUNTRY, NULL);
  1836.                             } while (country < 0 || country > 65);
  1837.                             onemove_jarl(whichjarl, country);
  1838.                             goto JARLMOVE_CONTINUE;
  1839.                     }   }
  1840.  
  1841.                     do
  1842.                     {   saywho(JARL, whichjarl, FALSE, FALSE);
  1843.                         sprintf
  1844.                         (   saystring2,
  1845.                             "%s %s, %s %ld %s %ld?",
  1846.                             GetCatalogStr(li.li_Catalog, MSG_IN,     "in"),
  1847.                             world[jarl[whichjarl].where].name,
  1848.                             GetCatalogStr(li.li_Catalog, MSG_MOVE,   "move"),
  1849.                             whichmove,
  1850.                             GetCatalogStr(li.li_Catalog, MSG_OF,     "of"),
  1851.                             moves
  1852.                         );
  1853.                         strcat(saystring, saystring2);
  1854.                         say(LOWER);
  1855.                         hint
  1856.                         (   (STRPTR) GetCatalogStr(li.li_Catalog, MSG_MOVE2,  "Move"),
  1857.                             (STRPTR) GetCatalogStr(li.li_Catalog, MSG_FINISH, "Finish")
  1858.                         );
  1859.  
  1860.                         do
  1861.                         {   country = getevent(COUNTRY, NULL);
  1862.                         } while ((country < -3 || country > 65) || country == -1);
  1863.                         if (country == -3)
  1864.                         {   break;
  1865.                         } elif (country == -2)
  1866.                         {   whichmove = 1;
  1867.                             unslot_jarl(whichjarl);
  1868.                             jarl[whichjarl].where = oldcountry;
  1869.                             move_jarl(whichjarl, TRUE);
  1870.                         } else
  1871.                         {   legal = FALSE;
  1872.                             for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
  1873.                             {   if (world[jarl[whichjarl].where].connection[whichconnection] == country)
  1874.                                 {   legal = TRUE;
  1875.                                     break; // for speed
  1876.                             }   }
  1877.                             if (legal && islegal(JARL, whichjarl, country, TRUE))
  1878.                             {   onemove_jarl(whichjarl, country);
  1879.                         }   }
  1880.                     } while (whichmove <= moves);
  1881.  
  1882. JARLMOVE_CONTINUE:
  1883.                     ;
  1884.  
  1885.                 } elif (hero[whichhero].control == AMIGA)
  1886.                 {
  1887.  
  1888. #ifndef QUICKMOVES
  1889.                     saywho(JARL, whichjarl, FALSE, FALSE);
  1890.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_MOVING, "is moving"));
  1891.                     strcat(saystring, "...");
  1892.                     say(LOWER);
  1893. #endif
  1894.  
  1895.                     do
  1896.                     {   assessment[CONNECTIONS + 1] = assess_jarl(whichjarl, jarl[whichjarl].where) - 1;
  1897.                         for (i = 0; i <= CONNECTIONS; i++)
  1898.                         {   assessment[i] = assess_jarl(whichjarl, world[jarl[whichjarl].where].connection[i]);
  1899.                         }
  1900.                         bestmove = -100;
  1901.                         for (i = 0; i <= CONNECTIONS + 1; i++)
  1902.                         {   if
  1903.                             (    assessment[i] >  bestmove
  1904.                              || (assessment[i] == bestmove && !(rand() % 2))
  1905.                             )
  1906.                             {   bestassessment = i;
  1907.                                 bestmove       = assessment[i];
  1908.                         }   }
  1909.  
  1910.                         if (bestassessment == CONNECTIONS + 1)
  1911.                         {   bestcountry = jarl[whichjarl].where;
  1912.                         } else
  1913.                         {   bestcountry = world[jarl[whichjarl].where].connection[bestassessment];
  1914.                         }
  1915.                         // assert(bestcountry >= 0 && bestcountry <= 65);
  1916.  
  1917.                         if
  1918.                         (   bestcountry != jarl[whichjarl].where // if moving
  1919.                          && !(world[bestcountry].visited)
  1920.                          && islegal(JARL, whichjarl, bestcountry, FALSE)
  1921.                         )
  1922.                         {   onemove_jarl(whichjarl, bestcountry);
  1923.                         } else
  1924.                         {   break;
  1925.                     }   }
  1926.                     while (whichmove <= moves);
  1927.                 }
  1928.  
  1929. JARLMOVE_END:
  1930.  
  1931.                 /* For humans and Amiga */
  1932.  
  1933.                 for (i = 0; i < whichmove; i++)
  1934.                 {   if (movearray[i] == hero[whichhero].where)
  1935.                     {   // jarl moved past hero during move
  1936.                         givegold(whichhero, whichjarl);
  1937.                 }   }
  1938.  
  1939.                 needtreasure(JARL, whichjarl, jarl[whichjarl].where, hero[whichhero].control);
  1940.                 needsord(JARL, whichjarl, jarl[whichjarl].where, hero[whichhero].control);
  1941.                 brosung(JARL, whichjarl, hero[whichhero].control);
  1942.  
  1943. #ifdef QUICKMOVES
  1944.                 if (hero[whichhero].control == HUMAN)
  1945.                 {   deselect_jarl(whichjarl, TRUE);
  1946.                 }
  1947. #else
  1948.                 deselect_jarl(whichjarl, TRUE);
  1949. #endif
  1950.  
  1951.         }   }
  1952.  
  1953. #ifdef QUICKMOVES
  1954.         if (hero[whichhero].control == AMIGA)
  1955.         {   refreshcounters();
  1956.         }
  1957. #endif
  1958.  
  1959. }   }
  1960.  
  1961. AGLOBAL void anykey(void)
  1962. {   getevent(ANYKEY, NULL);
  1963. }
  1964.  
  1965. MODULE SLONG getluck(SLONG whichhero)
  1966. {   SLONG result;
  1967.  
  1968.     hint("0","0");
  1969.  
  1970.     while(1)
  1971.     {   do
  1972.         {   result = getevent(MULTIKEYBOARD, NULL);
  1973.         } while (result < '0' || result > '9');
  1974.  
  1975.         result -= '0';
  1976.  
  1977.         if (result <= hero[whichhero].luck)
  1978.         {   hero[whichhero].luck -= result;
  1979.             return(result);
  1980.         } else
  1981.         {   return(0);
  1982. }   }   }
  1983.  
  1984. MODULE void amiga_rout(SLONG routedtype, SLONG routed)
  1985. {   SLONG decision, i, whichmove, moves;
  1986.     FLAG freemove, stop;
  1987.  
  1988.     if (routedtype == HERO)
  1989.     {   hero[routed].routed = TRUE;
  1990.     } elif (routedtype == JARL)
  1991.     {   jarl[routed].routed = TRUE;
  1992.     }
  1993.  
  1994.     moves = getmoves(routedtype, routed, FALSE);
  1995.     if (moves < 1)
  1996.     {   return;
  1997.     }
  1998.  
  1999.     saywho(routedtype, routed, FALSE, FALSE);
  2000.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_BEING_ROUTED, "is being routed"));
  2001.     strcat(saystring, "...");
  2002.     say(LOWER);
  2003.  
  2004.     for (i = 0; i <= 65; i++)
  2005.     {   world[i].visited = FALSE;
  2006.     }
  2007.  
  2008.     if (routedtype == HERO)
  2009.     {   world[hero[routed].where].visited = TRUE;
  2010.         freemove = FALSE;
  2011.  
  2012.         for (whichmove = 1; whichmove <= moves; whichmove++)
  2013.         {   stop = TRUE;
  2014.             for (i = 0; i <= CONNECTIONS; i++)
  2015.             {   if
  2016.                 (   world[hero[routed].where].connection[i] != -1
  2017.                  && world[world[hero[routed].where].connection[i]].visited == FALSE
  2018.                  && islegal(HERO, routed, world[hero[routed].where].connection[i], FALSE)
  2019.                 )
  2020.                 {   stop = FALSE;
  2021.                     break;
  2022.             }   }
  2023.             if (stop)
  2024.             {   break;
  2025.             }
  2026.             do
  2027.             {   decision = rand() % (CONNECTIONS + 1);
  2028.             } while
  2029.             (   world[hero[routed].where].connection[decision] == -1
  2030.              || world[world[hero[routed].where].connection[decision]].visited == TRUE
  2031.              || !islegal(HERO, routed, world[hero[routed].where].connection[decision], FALSE)
  2032.             );
  2033.  
  2034.             unslot_hero(routed);
  2035.             hero[routed].where = world[hero[routed].where].connection[decision];
  2036.             move_hero(routed, TRUE);
  2037.             if (checkfree(routed, &freemove))
  2038.             {   whichmove--;
  2039.     }   }   }
  2040.     elif (routedtype == JARL)
  2041.     {   world[jarl[routed].where].visited = TRUE;
  2042.  
  2043.         for (whichmove = 1; whichmove <= moves; whichmove++)
  2044.         {   stop = TRUE;
  2045.             for (i = 0; i <= CONNECTIONS; i++)
  2046.             {   if
  2047.                 (   world[jarl[routed].where].connection[i] != -1
  2048.                  && world[world[jarl[routed].where].connection[i]].visited == FALSE
  2049.                  && islegal(JARL, routed, world[jarl[routed].where].connection[i], FALSE)
  2050.                 )
  2051.                 {   stop = FALSE;
  2052.                     break;
  2053.             }   }
  2054.             if (stop)
  2055.             {   break;
  2056.             }
  2057.             do
  2058.             {   decision = rand() % (CONNECTIONS + 1);
  2059.             } while
  2060.             (   world[jarl[routed].where].connection[decision] == -1
  2061.              || world[world[jarl[routed].where].connection[decision]].visited == TRUE
  2062.              || !islegal(JARL, routed, world[jarl[routed].where].connection[decision], FALSE)
  2063.             );
  2064.  
  2065.             unslot_jarl(routed);
  2066.             jarl[routed].where = world[jarl[routed].where].connection[decision];
  2067.             move_jarl(routed, TRUE);
  2068.     }   }
  2069.     elif (routedtype == MONSTER)
  2070.     {   world[monster[routed].where].visited = TRUE;
  2071.  
  2072.         for (whichmove = 1; whichmove <= moves; whichmove++)
  2073.         {   stop = TRUE;
  2074.             for (i = 0; i <= CONNECTIONS; i++)
  2075.             {   if
  2076.                 (   world[monster[routed].where].connection[i] != -1
  2077.                  && world[world[monster[routed].where].connection[i]].visited == FALSE
  2078.                  && islegal(MONSTER, routed, world[monster[routed].where].connection[i], FALSE)
  2079.                 )
  2080.                 {   stop = FALSE;
  2081.                     break;
  2082.             }   }
  2083.             if (stop)
  2084.             {   break;
  2085.             }
  2086.             do
  2087.             {   decision = rand() % (CONNECTIONS + 1);
  2088.             } while
  2089.             (   world[monster[routed].where].connection[decision] == -1
  2090.              || world[world[monster[routed].where].connection[decision]].visited == TRUE
  2091.              || !islegal(MONSTER, routed, world[monster[routed].where].connection[decision], FALSE)
  2092.             );
  2093.  
  2094.             unslot_monster(routed);
  2095.             monster[routed].where = world[monster[routed].where].connection[decision];
  2096.             move_monster(routed, TRUE);
  2097. }   }   }
  2098.  
  2099. MODULE void human_rout(SLONG routedtype, SLONG routed, SLONG routerhero)
  2100. {   SLONG country,
  2101.           oldcountry = -1,
  2102.           moves,
  2103.           whichconnection,
  2104.           whichmove;
  2105.     FLAG  legal, freemove;
  2106.  
  2107.     moves = getmoves(routedtype, routed, FALSE);
  2108.  
  2109.     if (moves == 0)
  2110.     {   return;
  2111.     }
  2112.  
  2113.     whichmove = 1;
  2114.     freemove = FALSE;
  2115.     do
  2116.     {   saywho(HERO, routerhero, TRUE, FALSE);
  2117.         sprintf
  2118.         (   saystring2,
  2119.             "%s %ld %s %ld %s",
  2120.             GetCatalogStr(li.li_Catalog, MSG_ROUT, "rout"),
  2121.             whichmove,
  2122.             GetCatalogStr(li.li_Catalog, MSG_OF,   "of"),
  2123.             moves,
  2124.             GetCatalogStr(li.li_Catalog, MSG_FOR,  "for")
  2125.         );
  2126.         strcat(saystring, saystring2);
  2127.         saywho(routedtype, routed, FALSE, TRUE);
  2128.         strcat(saystring, "?");
  2129.         say(LOWER);
  2130.  
  2131.         do
  2132.         {   country = getevent(COUNTRY, NULL);
  2133.         } while ((country < -3 || country > 65) || country == -1);
  2134.         if (country == -3)
  2135.         {   break;
  2136.         } elif (country == -2)
  2137.         {   whichmove = 1;
  2138.             if (routedtype == HERO)
  2139.             {   unslot_hero(routed);
  2140.                 hero[routed].where = oldcountry;
  2141.                 move_hero(routed, TRUE);
  2142.                 freemove = FALSE;
  2143.             } elif (routedtype == JARL)
  2144.             {   unslot_jarl(routed);
  2145.                 jarl[routed].where = oldcountry;
  2146.                 move_jarl(routed, TRUE);
  2147.             } else
  2148.             {   // assert(routedtype == MONSTER);
  2149.                 unslot_monster(routed);
  2150.                 monster[routed].where = oldcountry;
  2151.                 move_monster(routed, TRUE);
  2152.         }   }
  2153.         else
  2154.         {   legal = FALSE;
  2155.             for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
  2156.             {   if
  2157.                 (   (routedtype == HERO    && world[hero[routed].where].connection[whichconnection] == country)
  2158.                  || (routedtype == JARL    && world[jarl[routed].where].connection[whichconnection] == country)
  2159.                  || (routedtype == MONSTER && world[monster[routed].where].connection[whichconnection] == country)
  2160.                 )
  2161.                 {   legal = TRUE;
  2162.                     break; // for speed
  2163.             }   }
  2164.             if (legal && islegal(routedtype, routed, country, TRUE))
  2165.             {   if (routedtype == HERO)
  2166.                 {   unslot_hero(routed);
  2167.                     hero[routed].where = country;
  2168.                     move_hero(routed, TRUE);
  2169.  
  2170.                     if (checkfree(routed, &freemove))
  2171.                     {   whichmove--;
  2172.                 }   }
  2173.                 elif (routedtype == JARL)
  2174.                 {   unslot_jarl(routed);
  2175.                     jarl[routed].where = country;
  2176.                     move_jarl(routed, TRUE);
  2177.                 } else
  2178.                 {   // assert(routedtype == MONSTER);
  2179.                     unslot_monster(routed);
  2180.                     monster[routed].where = country;
  2181.                     move_monster(routed, TRUE);
  2182.                 }
  2183.                 whichmove++;
  2184.         }   }
  2185.     } while (whichmove <= moves);
  2186. }
  2187.  
  2188. MODULE SLONG getmoves(SLONG countertype, SLONG whichcounter, FLAG freyfaxi)
  2189. {   SLONG moves;
  2190.  
  2191.     if (countertype == HERO)
  2192.     {   moves = hero[whichcounter].moves;
  2193.     } elif (countertype == MONSTER)
  2194.     {   // assert(!freyfaxi);
  2195.         moves = monster[whichcounter].moves;
  2196.     } else
  2197.     {   // assert(countertype == JARL);
  2198.         moves = jarl[whichcounter].moves;
  2199.     }
  2200.  
  2201.     if (freyfaxi)
  2202.     {   moves *= 2;
  2203.     }
  2204.  
  2205.     if
  2206.     (   countertype != MONSTER // so dragons don't use magic treasures
  2207.      && treasure[MAGICSHIRT].possessortype == countertype
  2208.      && treasure[MAGICSHIRT].possessor     == whichcounter
  2209.     )
  2210.     {   // assert(treasure[MAGICSHIRT].where == -1);
  2211.         moves++;
  2212.     }
  2213.  
  2214.     if (countertype == HERO && hero[whichcounter].rune == EON)
  2215.     {   moves++;
  2216.     }
  2217.  
  2218.     if
  2219.     (   (countertype == HERO && hero[whichcounter].loseturn)
  2220.      || (countertype == JARL && jarl[whichcounter].loseturn)
  2221.     )
  2222.     {   moves = 0;
  2223.     }
  2224.  
  2225.     /* If you are stuck at sea or on an island, and can't travel
  2226.        by sea, then you can't move at all that turn. */
  2227.     if (!islegal(countertype, whichcounter, hero[whichcounter].where, FALSE))
  2228.     {   moves = 0;
  2229.     }
  2230.  
  2231.     return(moves);
  2232. }
  2233.  
  2234. AGLOBAL void treasure_disappear(SLONG whichtreasure)
  2235. {   if (whichtreasure == FREYFAXI && faxirides >= 1)
  2236.     {   faxirides--;
  2237.     }
  2238.     if (whichtreasure != FREYFAXI || faxirides == 0)
  2239.     {   treasure[whichtreasure].possessortype = -1; // noone
  2240.         treasure[whichtreasure].possessor     = -1; // noone
  2241.         treasure[whichtreasure].where         = -1; // nowhere
  2242.         if (whichtreasure == FREYFAXI)
  2243.         {   faxirides = -1; // so it only disappears once
  2244.     }   }
  2245.     // the treasure in question won't be on the board at the moment anyway
  2246. }
  2247.  
  2248. MODULE void thor(SLONG whichhero)
  2249. {   SLONG whichprayer;
  2250.  
  2251.     if (hero[whichhero].god == THOR)
  2252.     {   hero[whichhero].god = -1;
  2253.         whichprayer = d6();
  2254.  
  2255.         if (whichprayer >= 1 && whichprayer <= 3)
  2256.         {   sprintf
  2257.             (   saystring,
  2258.                 "Thor %s %s %s.",
  2259.                 GetCatalogStr(li.li_Catalog, MSG_DECIDES_THAT_HERO,  "decides that hero"),
  2260.                 hero[whichhero].name,
  2261.                 GetCatalogStr(li.li_Catalog, MSG_DESERVES_NO_REWARD, "deserves no reward")
  2262.             );
  2263.         } elif (whichprayer == 4 || whichprayer == 5)
  2264.         {   hero[whichhero].glory++;
  2265.  
  2266.             sprintf
  2267.             (   saystring,
  2268.                 "Thor %s %s %s.",
  2269.                 GetCatalogStr(li.li_Catalog, MSG_REWARDS_HERO,       "rewards hero"),
  2270.                 hero[whichhero].name,
  2271.                 GetCatalogStr(li.li_Catalog, MSG_B_S_T_H_G_1_G,      "by speaking to him, granting 1 glory")
  2272.             );
  2273.         } else
  2274.         {   // assert(whichprayer == 6);
  2275.  
  2276.             hero[whichhero].glory += 2;
  2277.  
  2278.             sprintf
  2279.             (   saystring,
  2280.                 "Thor %s %s %s.",
  2281.                 GetCatalogStr(li.li_Catalog, MSG_HONOURS_HERO,       "honours hero"),
  2282.                 hero[whichhero].name,
  2283.                 GetCatalogStr(li.li_Catalog, MSG_B_E_W_H_G_2_G,      "by eating with him, granting 2 glory")
  2284.             );
  2285.         }
  2286.  
  2287.         say(LOWER);
  2288.         anykey();
  2289. }   }
  2290.  
  2291. MODULE void dospell(SLONG spell, SLONG caster)
  2292. {   SLONG whichhero, whichjarl, whichmonster;
  2293.  
  2294.     if (spell == HAGALL || spell == JARA || d6() <= 3) // if it's a spell which doesn't have a saving throw, or the saving throw is missed
  2295.     {   strcat(saystring, ".");
  2296.         say(LOWER);
  2297.         anykey();
  2298.  
  2299.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  2300.         {   if
  2301.             (   hero[whichhero].control != NONE
  2302.              && hero[whichhero].alive
  2303.              && hero[whichhero].where == monster[caster].where
  2304.             )
  2305.             {   if (hero[whichhero].rune == SYGIL && d6() <= 3)
  2306.                 {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  2307.                     strcat(saystring, " ");
  2308.                     strcat(saystring, hero[whichhero].name);
  2309.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_RUNE_PROTECTS_HIM, "'s rune protects him"));
  2310.                     strcat(saystring, ".");
  2311.                     say(LOWER);
  2312.                     anykey();
  2313.                 } else
  2314.                 {   if (spell == HAGALL)
  2315.                     {   hero[whichhero].hagall = TRUE;
  2316.                         hero[whichhero].sea    = BAD;
  2317.                     } elif (spell == JARA)
  2318.                     {   hero[whichhero].loseturn = TRUE;
  2319.                     } elif (spell == NIED)
  2320.                     {   hero[whichhero].loseturn = TRUE;
  2321.                         hero[whichhero].attacking = FALSE;
  2322.                         deselect_hero(whichhero, TRUE);
  2323.                     } elif (spell == WYNN)
  2324.                     {   hero[whichhero].glory -= 2;
  2325.                         if (hero[whichhero].glory < 0)
  2326.                         {   hero[whichhero].glory = 0;
  2327.                         }
  2328.                         amiga_rout(HERO, whichhero);
  2329.                         hero[whichhero].attacking = FALSE;
  2330.                         deselect_hero(whichhero, TRUE);
  2331.                     } elif (spell == YR)
  2332.                     {   wound(MONSTER, caster, -1, HERO, whichhero, whichhero);
  2333.                         hero[whichhero].attacking = FALSE;
  2334.                         deselect_hero(whichhero, TRUE);
  2335.         }   }   }   }
  2336.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2337.         {   if
  2338.             (   jarl[whichjarl].alive
  2339.              && jarl[whichjarl].where == monster[caster].where
  2340.             )
  2341.             {   if (spell == HAGALL)
  2342.                 {   jarl[whichjarl].hagall = TRUE;
  2343.                     jarl[whichjarl].sea    = BAD;
  2344.                 } elif (spell == JARA)
  2345.                 {   jarl[whichjarl].loseturn = TRUE;
  2346.                 } elif (spell == NIED)
  2347.                 {   jarl[whichjarl].loseturn = TRUE;
  2348.                     jarl[whichjarl].attacking = FALSE;
  2349.                     deselect_jarl(whichjarl, TRUE);
  2350.                 } elif (spell == WYNN)
  2351.                 {   amiga_rout(JARL, whichjarl);
  2352.                     jarl[whichjarl].attacking = FALSE;
  2353.                     deselect_jarl(whichjarl, TRUE);
  2354.                 } elif (spell == YR)
  2355.                 {   if (jarl[whichjarl].face == FACEUP)
  2356.                     {   wound(MONSTER, caster, -1, JARL, whichjarl, jarl[whichjarl].hero);
  2357.                         jarl[whichjarl].attacking = FALSE;
  2358.                         deselect_jarl(whichjarl, TRUE);
  2359.         }   }   }   }
  2360.  
  2361.         if (spell == HAGALL)
  2362.         {   for (whichmonster = 0; whichmonster <= monsters; whichmonster++)
  2363.             {   if
  2364.                 (   monster[whichmonster].alive
  2365.                  && monster[whichmonster].where == monster[caster].where
  2366.                 )
  2367.                 {   monster[whichmonster].hagall = TRUE;
  2368.                     monster[whichmonster].sea    = BAD;
  2369.     }   }   }   }
  2370.     else
  2371.     {   strcat(saystring, ", ");
  2372.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BUT_IT_FIZZLES, "but it fizzles"));
  2373.         strcat(saystring, "!");
  2374.         say(LOWER);
  2375.         anykey();
  2376. }   }
  2377.  
  2378. MODULE void cast(SLONG caster, SLONG whichspell)
  2379. {   sprintf
  2380.     (   saystring,
  2381.         "%s %s %s ",
  2382.         monstertypes[monster[caster].species],
  2383.         monster[caster].name,
  2384.         GetCatalogStr(li.li_Catalog, MSG_CASTS, "casts")
  2385.     );
  2386.  
  2387.     switch(whichspell)
  2388.     {
  2389.     case HAGALL:
  2390.         strcat(saystring, "Hagall (");
  2391.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAIL, "hail"));
  2392.         strcat(saystring, ")");
  2393.  
  2394.         dospell(HAGALL, caster);
  2395.     break;
  2396.     case IS:
  2397.         world[monster[caster].where].is = TRUE;
  2398.         darken();
  2399.  
  2400.         strcat(saystring, "Is (");
  2401.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ICE, "ice"));
  2402.         strcat(saystring, ").");
  2403.  
  2404.         say(LOWER);
  2405.         anykey();
  2406.     break;
  2407.     case JARA:
  2408.         strcat(saystring, "Jara (");
  2409.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LOSE_NEXT_TURN, "lose next turn"));
  2410.         strcat(saystring, ")");
  2411.  
  2412.         dospell(JARA, caster);
  2413.     break;
  2414.     case NIED:
  2415.         strcat(saystring, "Nied (");
  2416.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_N_R_A_L_N_T, "no result and lose next turn"));
  2417.         strcat(saystring, ")");
  2418.  
  2419.         dospell(NIED, caster);
  2420.     break;
  2421.     case WYNN:
  2422.         strcat(saystring, "Wynn (");
  2423.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FLEEING, "fleeing"));
  2424.         strcat(saystring, ")");
  2425.  
  2426.         dospell(WYNN, caster);
  2427.     break;
  2428.     case YR:
  2429.         strcat(saystring, "Yr (");
  2430.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_WOUNDING, "wounding"));
  2431.         strcat(saystring, ")");
  2432.  
  2433.         dospell(YR, caster);
  2434.     break;
  2435.     default:
  2436.         // assert(0);
  2437.     break;
  2438. }   }
  2439.  
  2440. MODULE void getdefender(SLONG attackhero, SLONG here)
  2441. {   FLAG  done = FALSE;
  2442.     SLONG counter, countertype, whichattack, whichjarl;
  2443.  
  2444.     do
  2445.     {   saywho(HERO, attackhero, TRUE, FALSE);
  2446.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SELECT_DEFENDER, "select defender"));
  2447.         strcat(saystring, "?");
  2448.         say(LOWER);
  2449.         hint
  2450.         (   (STRPTR) GetCatalogStr(li.li_Catalog, MSG_SELECT, "Select"),
  2451.             (STRPTR) GetCatalogStr(li.li_Catalog, MSG_CANCEL, "Cancel")
  2452.         );
  2453.  
  2454.         counter = getevent(COUNTER, &countertype);
  2455.         if (counter == -2 || counter == -3)
  2456.         {   // user wants to quit (back to `select attacker')
  2457.             if (hero[attackhero].attacking)
  2458.             {   deselect_hero(attackhero, TRUE);
  2459.                 hero[attackhero].attacking = FALSE;
  2460.             }
  2461.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2462.             {   if (jarl[whichjarl].alive && jarl[whichjarl].attacking)
  2463.                 {   deselect_jarl(whichjarl, TRUE);
  2464.                     jarl[whichjarl].attacking = FALSE;
  2465.             }   }
  2466.             return;
  2467.         } elif (countertype == HERO) // if an enemy hero
  2468.         {   if (counter != attackhero && hero[counter].where == here)
  2469.             {   done = TRUE;
  2470.         }   }
  2471.         elif (countertype == JARL) // if an enemy jarl
  2472.         {   if (jarl[counter].hero != attackhero && jarl[counter].where == here)
  2473.             {   done = TRUE;
  2474.         }   }
  2475.         elif (countertype == MONSTER) // if a monster
  2476.         {   if (monster[counter].where == here)
  2477.             {   done = TRUE;
  2478.         }   }
  2479.         elif (countertype == KINGDOM)
  2480.         {   if
  2481.             (   world[counter].hero != attackhero
  2482.              && counter <= 35
  2483.              && counter == here
  2484.             )
  2485.             {   if (world[counter].is)
  2486.                 {   saywho(KINGDOM, counter, FALSE, FALSE);
  2487.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_COVERED_WITH_ICE, "is covered with ice"));
  2488.                     strcat(saystring, ".");
  2489.                     say(LOWER);
  2490.                     anykey();
  2491.                 } else
  2492.                 {   done = TRUE;
  2493.         }   }   }
  2494.  
  2495.         if (done)
  2496.         {   if (hero[attackhero].attacking)
  2497.             {   // check if the hero has already fought this
  2498.                 for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  2499.                 {   if
  2500.                     (   hero[attackhero].attacktype[whichattack] == countertype
  2501.                      && hero[attackhero].attacked[whichattack]   == counter
  2502.                     )
  2503.                     {   done = FALSE;
  2504.  
  2505.                         saywho(HERO, attackhero, FALSE, FALSE);
  2506.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_H_A_F, "has already fought"));
  2507.                         saywho(countertype, counter, FALSE, TRUE);
  2508.                         strcat(saystring, " ");
  2509.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_THIS_TURN, "this turn"));
  2510.                         strcat(saystring, ".");
  2511.                         say(LOWER);
  2512.                         anykey();
  2513.                         break; // for speed
  2514.             }   }   }
  2515.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2516.             {   if (jarl[whichjarl].attacking)
  2517.                 {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  2518.                     {   if
  2519.                         (   jarl[whichjarl].attacktype[whichattack] == countertype
  2520.                          && jarl[whichjarl].attacked[whichattack]   == counter
  2521.                         )
  2522.                         {   done = FALSE;
  2523.  
  2524.                             saywho(JARL, whichjarl, FALSE, FALSE);
  2525.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_H_A_F, "has already fought"));
  2526.                             saywho(countertype, counter, FALSE, TRUE);
  2527.                             strcat(saystring, " ");
  2528.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_THIS_TURN, "this turn"));
  2529.                             strcat(saystring, ".");
  2530.                             say(LOWER);
  2531.                             anykey();
  2532.                             break; // for speed
  2533.     }   }   }   }   }   }
  2534.     while (!done);
  2535.  
  2536.     // ok, going ahead with the battle
  2537.     if (countertype == JARL && jarl[counter].face == FACEDOWN)
  2538.     {   revealjarl(counter, TRUE);
  2539.     }
  2540.     if (hero[attackhero].attacking)
  2541.     {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  2542.         {   if (hero[attackhero].attacktype[whichattack] == -1)
  2543.             {   hero[attackhero].attacktype[whichattack] = countertype;
  2544.                 hero[attackhero].attacked[whichattack]   = counter;
  2545.                 break;
  2546.     }   }   }
  2547.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2548.     {   if (jarl[whichjarl].attacking)
  2549.         {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  2550.             {   if (jarl[whichjarl].attacktype[whichattack] == -1)
  2551.                 {   jarl[whichjarl].attacktype[whichattack] = countertype;
  2552.                     jarl[whichjarl].attacked[whichattack]   = counter;
  2553.                     break;
  2554.     }   }   }   }
  2555.  
  2556.     dobattle(countertype, counter, attackhero);
  2557. }
  2558.  
  2559. MODULE void needsord(SLONG countertype, SLONG counter, SLONG whichcountry, SLONG control)
  2560. {   SLONG result = -1, // to avoid spurious compiler warnings
  2561.           whichsord;
  2562.  
  2563.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  2564.     {   if
  2565.         (   sord[whichsord].possessortype == countertype
  2566.          && sord[whichsord].possessor     == counter
  2567.         )
  2568.         {   return;
  2569.     }   }
  2570.  
  2571.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  2572.     {   if
  2573.         (   sord[whichsord].possessortype == KINGDOM
  2574.          && sord[whichsord].where == whichcountry
  2575.         )
  2576.         {   // assert(sord[whichsord].possessor = -1);
  2577.  
  2578.             saywho(countertype, counter, FALSE, FALSE);
  2579.  
  2580.             if (control == HUMAN)
  2581.             {   sprintf
  2582.                 (   saystring2,
  2583.                     "%s %s, %s %s (%s/%s)?",
  2584.                     GetCatalogStr(li.li_Catalog, MSG_IN,         "in"),
  2585.                     world[whichcountry].name,
  2586.                     GetCatalogStr(li.li_Catalog, MSG_TAKE_SWORD, "take sword"),
  2587.                     sord[whichsord].name,
  2588.                     GetCatalogStr(li.li_Catalog, MSG_CHAR_YES,   "Y"),
  2589.                     GetCatalogStr(li.li_Catalog, MSG_CHAR_NO,    "N")
  2590.                 );
  2591.                 strcat(saystring, saystring2);
  2592.                 say(LOWER);
  2593.                 do
  2594.                 {   result = getevent(YNKEYBOARD, NULL);
  2595.                 } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  2596.             }
  2597.  
  2598.             if (control == AMIGA || result == onekey[ONEKEY_YES])
  2599.             {   remove_sord(whichsord, TRUE);
  2600.                 sord[whichsord].possessortype = countertype;
  2601.                 sord[whichsord].possessor     = counter;
  2602.                 sord[whichsord].where         = -1;
  2603.             }
  2604.             if (control == AMIGA)
  2605.             {   sprintf
  2606.                 (   saystring2,
  2607.                     "%s %s.",
  2608.                     GetCatalogStr(li.li_Catalog, MSG_TAKES_SWORD, "takes sword"),
  2609.                     sord[whichsord].name
  2610.                 );
  2611.                 strcat(saystring, saystring2);
  2612.                 say(LOWER);
  2613.                 anykey();
  2614.             }
  2615.             if (result == onekey[ONEKEY_YES] || control == AMIGA)
  2616.             {   return;
  2617. }   }   }   }
  2618.  
  2619. MODULE void brosung(SLONG countertype, SLONG whichcounter, SLONG control)
  2620. {   SLONG result, whichconnection, whichmonster, whichtreasure, where;
  2621.  
  2622.     if
  2623.     (   control == AMIGA
  2624.      || treasure[BROSUNGNECKLACE].possessortype != countertype
  2625.      || treasure[BROSUNGNECKLACE].possessor     != whichcounter
  2626.     )
  2627.     {   return;
  2628.     }
  2629.  
  2630.     for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
  2631.     {   if (countertype == HERO)
  2632.         {   where = world[hero[whichcounter].where].connection[whichconnection];
  2633.         } else
  2634.         {   // assert(countertype == JARL);
  2635.             where = world[jarl[whichcounter].where].connection[whichconnection];
  2636.         }
  2637.         if (where == -1)
  2638.         {   break;
  2639.         }
  2640.         for (whichmonster = 0; whichmonster <= monsters; whichmonster++)
  2641.         {   if
  2642.             (   monster[whichmonster].alive
  2643.              && monster[whichmonster].species == DRAGON
  2644.              && monster[whichmonster].where == where
  2645.             )
  2646.             {   // there is a dragon here
  2647.                 for (whichtreasure = 0; whichtreasure <= treasures; whichtreasure++)
  2648.                 {   if
  2649.                     (   treasure[whichtreasure].possessortype == MONSTER
  2650.                      && treasure[whichtreasure].possessor == whichmonster
  2651.                     )
  2652.                     {   saywho(countertype, whichcounter, TRUE, FALSE);
  2653.                         sprintf
  2654.                         (   saystring2,
  2655.                             "%s %s %s %s %s (%s/%s)?",
  2656.                             GetCatalogStr(li.li_Catalog, MSG_EXCHANGE_THE, "exchange the"),
  2657.                             treasure[BROSUNGNECKLACE].name,
  2658.                             GetCatalogStr(li.li_Catalog, MSG_WITH,         "with"),
  2659.                             monstertypes[DRAGON],
  2660.                             monster[whichmonster].name,
  2661.                             GetCatalogStr(li.li_Catalog, MSG_CHAR_YES,     "Y"),
  2662.                             GetCatalogStr(li.li_Catalog, MSG_CHAR_NO,      "N")
  2663.                         );
  2664.                         strcat(saystring, saystring2);
  2665.                         say(LOWER);
  2666.  
  2667.                         do
  2668.                         {   result = getevent(YNKEYBOARD, NULL);
  2669.                         } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  2670.                         if (result == onekey[ONEKEY_YES])
  2671.                         {   // give the dragon's treasure to the hero/jarl
  2672.                             treasure[whichtreasure].possessortype   = countertype;
  2673.                             treasure[whichtreasure].possessor       = whichcounter;
  2674.  
  2675.                             saywho(countertype, whichcounter, FALSE, FALSE);
  2676.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_THE, "takes the"));
  2677.                             strcat(saystring, " ");
  2678.                             strcat(saystring, treasure[whichtreasure].name);
  2679.                             strcat(saystring, ".");
  2680.                             say(LOWER);
  2681.  
  2682.                             // give the hero/jarl's treasure to the dragon
  2683.                             treasure[BROSUNGNECKLACE].possessortype = MONSTER;
  2684.                             treasure[BROSUNGNECKLACE].possessor     = whichmonster;
  2685.                             break;
  2686. }   }   }   }   }   }   }
  2687.  
  2688. AGLOBAL void promote(SLONG whichhero, SLONG whichjarl)
  2689. {   remove_jarl(whichjarl, TRUE);
  2690.     jarl[whichjarl].alive     =
  2691.     hero[whichhero].wounded   = FALSE;
  2692.     hero[whichhero].alive     = TRUE;
  2693.     hero[whichhero].promoted  = whichjarl;
  2694.     hero[whichhero].name      = jarl[whichjarl].name;
  2695.     hero[whichhero].moves     = jarl[whichjarl].moves;
  2696.     hero[whichhero].strength  = jarl[whichjarl].strength;
  2697.     hero[whichhero].where     = jarl[whichjarl].where;
  2698.     hero[whichhero].homewhere = jarl[whichjarl].homewhere;
  2699.     hero[whichhero].hagall    = jarl[whichjarl].hagall;
  2700.     hero[whichhero].loseturn  = jarl[whichjarl].loseturn;
  2701.     hero[whichhero].wealth    = jarl[whichjarl].wealth;
  2702.     hero[whichhero].god       =
  2703.     hero[whichhero].rune      = -1;
  2704.     hero[whichhero].maidens   =
  2705.     hero[whichhero].glory     = 0;
  2706.     deselect_hero(whichhero, TRUE);
  2707.     move_hero(whichhero, TRUE);
  2708. }
  2709.  
  2710. AGLOBAL void withdraw(SLONG whichhero)
  2711. {   SLONG whichcountry, whichjarl;
  2712.  
  2713.     hero[whichhero].verydead = TRUE;
  2714.  
  2715.     // all the jarls of the dead hero are freed
  2716.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2717.     {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  2718.         {   jarl[whichjarl].hero = -1;
  2719.     }   }
  2720.  
  2721.     // all the kingdoms of the dead hero declare independence
  2722.     for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  2723.     {   if (world[whichcountry].hero == whichhero)
  2724.         {   world[whichcountry].hero = -1;
  2725.     }   }
  2726.  
  2727.     darken();
  2728. }
  2729.  
  2730. MODULE void needtreasure(SLONG countertype, SLONG counter, SLONG whichcountry, SLONG control)
  2731. {   SLONG result = -1, // to avoid spurious compiler warnings
  2732.           whichtreasure;
  2733.  
  2734.     for (whichtreasure = 0; whichtreasure <= treasures; whichtreasure++)
  2735.     {   if
  2736.         (   treasure[whichtreasure].possessortype == KINGDOM
  2737.          && treasure[whichtreasure].where == whichcountry
  2738.         )
  2739.         {   // assert(treasure[whichtreasure].possessor = -1);
  2740.  
  2741.             saywho(countertype, counter, FALSE, FALSE);
  2742.             if (control == HUMAN)
  2743.             {   sprintf
  2744.                 (   saystring2,
  2745.                     "%s %s, %s %s (%s/%s)?",
  2746.                     GetCatalogStr(li.li_Catalog, MSG_IN,         "in"),
  2747.                     world[whichcountry].name,
  2748.                     GetCatalogStr(li.li_Catalog, MSG_TAKE_THE,   "take the"),
  2749.                     treasure[whichtreasure].name,
  2750.                     GetCatalogStr(li.li_Catalog, MSG_CHAR_YES,   "Y"),
  2751.                     GetCatalogStr(li.li_Catalog, MSG_CHAR_NO,    "N")
  2752.                 );
  2753.             } else
  2754.             {   sprintf
  2755.                 (   saystring2,
  2756.                     "%s %s.",
  2757.                     GetCatalogStr(li.li_Catalog, MSG_TAKES_THE, "takes the"),
  2758.                     treasure[whichtreasure].name
  2759.                 );
  2760.             }
  2761.             strcat(saystring, saystring2);
  2762.             say(LOWER);
  2763.  
  2764.             if (control == HUMAN)
  2765.             {   do
  2766.                 {   result = getevent(YNKEYBOARD, NULL);
  2767.                 } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  2768.             } else
  2769.             {   anykey();
  2770.             }
  2771.  
  2772.             if (control == AMIGA || result == onekey[ONEKEY_YES])
  2773.             {   remove_treasure(whichtreasure, TRUE);
  2774.                 treasure[whichtreasure].possessortype = countertype;
  2775.                 treasure[whichtreasure].possessor     = counter;
  2776.                 treasure[whichtreasure].where         = -1;
  2777. }   }   }   }
  2778.  
  2779. AGLOBAL void pad(STRPTR thestring)
  2780. {   SLONG i, length;
  2781.  
  2782.     length = strlen(thestring);
  2783.  
  2784.     if (length < 22)
  2785.     {   for (i = length; i <= 22; i++)
  2786.         {   strcat(thestring, " ");
  2787. }   }   }
  2788.  
  2789. AGLOBAL void print_location(SLONG whichcountry, SLONG index)
  2790. {   sprintf(label[index], "%s:", GetCatalogStr(li.li_Catalog, MSG_LOCATION, "Location"));
  2791.     sprintf
  2792.     (   line[LEFTSIDE][index],
  2793.         "%s (%ld)",
  2794.         world[whichcountry].name,
  2795.         world[whichcountry].tax
  2796.     );
  2797. }
  2798. AGLOBAL void print_sea(SLONG sea_value, SLONG index)
  2799. {   sprintf(label[index], "%s?", GetCatalogStr(li.li_Catalog, MSG_MOVE_BY_SEA, "Move by sea"));
  2800.     if (sea_value == NORMAL)
  2801.     {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  2802.     } elif (sea_value == BAD)
  2803.     {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  2804.     } else
  2805.     {   // assert(sea_value == GOOD);
  2806.         strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_SPECIAL, "Special"));
  2807. }   }
  2808. AGLOBAL void print_hagall(SLONG hagall_value, SLONG index)
  2809. {   strcpy(label[index], "Hagall (");
  2810.     strcat(label[index], GetCatalogStr(li.li_Catalog, MSG_HAIL, "hail"));
  2811.     strcat(label[index], ")?");
  2812.     if (hagall_value)
  2813.     {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  2814.     } else
  2815.     {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  2816. }   }
  2817. AGLOBAL void print_paralyzed(SLONG loseturn_value, SLONG index)
  2818. {   sprintf(label[index], "Jara (%s)?", GetCatalogStr(li.li_Catalog, MSG_LOSE_TURN, "lose turn"));
  2819.     if (loseturn_value)
  2820.     {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  2821.     } else
  2822.     {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  2823. }   }
  2824. AGLOBAL void print_routed(SLONG routed_value, SLONG index)
  2825. {   sprintf(label[index], "%s?", GetCatalogStr(li.li_Catalog, MSG_ROUTED, "Routed"));
  2826.     if (routed_value)
  2827.     {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  2828.     } else
  2829.     {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  2830. }   }
  2831.  
  2832. MODULE void amiga_attack(SLONG attackhero, SLONG defendtype, SLONG defender, SLONG whichcountry)
  2833. {   SLONG whichattack, whichjarl;
  2834.  
  2835.     // OK, going ahead with the battle
  2836.  
  2837.     getattackers(attackhero, whichcountry, TRUE);
  2838.     if (defendtype == JARL && jarl[defender].face == FACEDOWN)
  2839.     {   revealjarl(defender, TRUE);
  2840.     }
  2841.     if (hero[attackhero].attacking)
  2842.     {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  2843.         {   if (hero[attackhero].attacktype[whichattack] == -1)
  2844.             {   hero[attackhero].attacktype[whichattack] = defendtype;
  2845.                 hero[attackhero].attacked[whichattack]   = defender;
  2846.                 break;
  2847.     }   }   }
  2848.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2849.     {   if (jarl[whichjarl].attacking)
  2850.         {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  2851.             {   if (jarl[whichjarl].attacktype[whichattack] == -1)
  2852.                 {   jarl[whichjarl].attacktype[whichattack] = defendtype;
  2853.                     jarl[whichjarl].attacked[whichattack]   = defender;
  2854.                     break;
  2855.     }   }   }   }
  2856.  
  2857.     saywho(HERO, attackhero, FALSE, FALSE);
  2858.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKS, "attacks"));
  2859.     saywho(defendtype, defender, FALSE, TRUE);
  2860.     strcat(saystring, ".");
  2861.     say(LOWER);
  2862.     anykey();
  2863.  
  2864.     dobattle(defendtype, defender, attackhero);
  2865. }
  2866.  
  2867. MODULE FLAG ask_treasure(SLONG countertype, SLONG whichcounter, SLONG whichtreasure)
  2868. {   SLONG result;
  2869.  
  2870.     saywho(countertype, whichcounter, TRUE, FALSE);
  2871.     if (whichtreasure == FREYFAXI)
  2872.     {   sprintf
  2873.         (   saystring2,
  2874.             "%s %s (%ld %s) (%s/%s)?",
  2875.             GetCatalogStr(li.li_Catalog, MSG_RIDE_THE,  "ride the" ),
  2876.             treasure[FREYFAXI].name,
  2877.             faxirides,
  2878.             GetCatalogStr(li.li_Catalog, MSG_RIDES2,    "rides"    ),
  2879.             GetCatalogStr(li.li_Catalog, MSG_CHAR_YES,  "Y"        ),
  2880.             GetCatalogStr(li.li_Catalog, MSG_CHAR_NO,   "N"        )
  2881.         );
  2882.     } elif (whichtreasure == HEALINGPOTION)
  2883.     {   sprintf
  2884.         (   saystring2,
  2885.             "%s %s (%s/%s)?",
  2886.             GetCatalogStr(li.li_Catalog, MSG_DRINK_THE, "drink the"),
  2887.             treasure[whichtreasure].name,
  2888.             GetCatalogStr(li.li_Catalog, MSG_CHAR_YES,  "Y"        ),
  2889.             GetCatalogStr(li.li_Catalog, MSG_CHAR_NO,   "N"        )
  2890.         );
  2891.     } else
  2892.     {   // assert(whichtreasure == TELEPORTSCROLL);
  2893.         sprintf
  2894.         (   saystring2,
  2895.             "%s %s (%s/%s)?",
  2896.             GetCatalogStr(li.li_Catalog, MSG_READ_THE,  "read the" ),
  2897.             treasure[whichtreasure].name,
  2898.             GetCatalogStr(li.li_Catalog, MSG_CHAR_YES,  "Y"        ),
  2899.             GetCatalogStr(li.li_Catalog, MSG_CHAR_NO,   "N"        )
  2900.         );
  2901.     }
  2902.     strcat(saystring, saystring2);
  2903.     say(LOWER);
  2904.  
  2905.     do
  2906.     {    result = getevent(YNKEYBOARD, NULL);
  2907.     } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  2908.     if (result == onekey[ONEKEY_YES])
  2909.     {   return(TRUE);
  2910.     }
  2911.     return(FALSE);
  2912. }
  2913.  
  2914. AGLOBAL void saywho(SLONG countertype, SLONG counter, FLAG comma, FLAG lowercase)
  2915. {   if (!lowercase)
  2916.     {   saystring[0] = 0;
  2917.     } else
  2918.     {   strcat(saystring, " ");
  2919.     }
  2920.     if (countertype == HERO)
  2921.     {   if (!lowercase)
  2922.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  2923.         } else
  2924.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO2, "hero"));
  2925.         }
  2926.         strcat(saystring, " ");
  2927.         strcat(saystring, hero[counter].name);
  2928.     } elif (countertype == JARL)
  2929.     {   if (jarl[counter].hero != -1)
  2930.         {   if (!lowercase)
  2931.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  2932.             } else
  2933.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO2, "hero"));
  2934.             }
  2935.             strcat(saystring, " ");
  2936.             strcat(saystring, hero[jarl[counter].hero].name);
  2937.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_JARL, "'s jarl"));
  2938.         } else
  2939.         {   if (!lowercase)
  2940.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_JARL, "Jarl"));
  2941.             } else
  2942.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_JARL2, "jarl"));
  2943.         }   }
  2944.         strcat(saystring, " ");
  2945.         strcat(saystring, jarl[counter].name);
  2946.     } elif (countertype == MONSTER)
  2947.     {   strcat(saystring, monstertypes[monster[counter].species]);
  2948.         strcat(saystring, " ");
  2949.         strcat(saystring, monster[counter].name);
  2950.     } else
  2951.     {   // assert(countertype == KINGDOM);
  2952.         if (world[counter].hero != -1)
  2953.         {   if (!lowercase)
  2954.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  2955.             } else
  2956.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO2, "hero"));
  2957.             }
  2958.             strcat(saystring, " ");
  2959.             strcat(saystring, hero[world[counter].hero].name);
  2960.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_KINGDOM, "'s kingdom"));
  2961.         } else
  2962.         {   if (!lowercase)
  2963.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_KINGDOM, "Kingdom"));
  2964.             } else
  2965.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_KINGDOM2, "kingdom"));
  2966.         }   }
  2967.         strcat(saystring, " ");
  2968.         strcat(saystring, world[counter].name);
  2969.         strcat(saystring, " (");
  2970.         stcl_d(numberstring, world[counter].tax);
  2971.         strcat(saystring, numberstring);
  2972.         strcat(saystring, ")");
  2973.     }
  2974.  
  2975.     if (!lowercase)
  2976.     {   if (comma)
  2977.         {   strcat(saystring, ",");
  2978.         }
  2979.         strcat(saystring, " ");
  2980. }   }
  2981.  
  2982. MODULE FLAG attackersleft(void)
  2983. {   SLONG whichhero, whichjarl;
  2984.  
  2985.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  2986.     {   if (hero[whichhero].attacking)
  2987.         {   return(TRUE);
  2988.     }   }
  2989.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2990.     {   if (jarl[whichjarl].attacking)
  2991.         {   return(TRUE);
  2992.     }   }
  2993.     return(FALSE);
  2994. }
  2995.  
  2996. MODULE SLONG getattackers(SLONG whichhero, SLONG whichcountry, FLAG real)
  2997. {   SLONG whichjarl,
  2998.           totalstrength = 0;
  2999.     FLAG  ok            = FALSE;
  3000.  
  3001.     if
  3002.     (   hero[whichhero].alive
  3003.      && !hero[whichhero].routed
  3004.      && hero[whichhero].where == whichcountry
  3005.     )
  3006.     {   if (real)
  3007.         {   hero[whichhero].attacking = TRUE;
  3008.             select_hero(whichhero, FALSE);
  3009.         }
  3010.         ok = TRUE;
  3011.         totalstrength += hero[whichhero].strength;
  3012.     }
  3013.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3014.     {   if
  3015.         (   jarl[whichjarl].alive
  3016.          && jarl[whichjarl].hero == whichhero
  3017.          && !jarl[whichjarl].routed
  3018.          && jarl[whichjarl].where == whichcountry
  3019.         )
  3020.         {   if (real)
  3021.             {   jarl[whichjarl].attacking = TRUE;
  3022.                 select_jarl(whichjarl, FALSE);
  3023.             }
  3024.             ok = TRUE;
  3025.             totalstrength += jarl[whichjarl].strength;
  3026.     }   }
  3027.     if (ok && real)
  3028.     {   refreshcounters();
  3029.     }
  3030.     return(totalstrength);
  3031. }
  3032.  
  3033. AGLOBAL void phase1(void)
  3034. {   SLONG besthero = -1,
  3035.           glory,
  3036.           whichhero,
  3037.           whichjarl,
  3038.           whichmonster,
  3039.           whichorder;
  3040.     FLAG  done;
  3041.  
  3042.    /* "1. MOVEMENT. All heroes and jarls move. The hero with the most
  3043.         glory and his or her jarls move first. In cases of ties the heroes
  3044.         roll dice to see who goes first, with the highest roll going
  3045.         first.
  3046.  
  3047.         A counter may move as many areas as its movement factor. Each area
  3048.         is defined by colour or, in the case of sea areas, by dividing
  3049.         lines. Counters may move and remain in sea areas just as if they
  3050.         were on land. There is no difference between land movement and sea
  3051.         movement." */
  3052.  
  3053.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3054.     {   hero[whichhero].moved  =
  3055.         hero[whichhero].hagall =
  3056.         hero[whichhero].routed = FALSE;
  3057.     }
  3058.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3059.     {   jarl[whichjarl].hagall =
  3060.         jarl[whichjarl].routed = FALSE;
  3061.     }
  3062.     for (whichmonster = 0; whichmonster <= monsters; whichmonster++)
  3063.     {   monster[whichmonster].hagall = FALSE;
  3064.     }
  3065.  
  3066.     for (whichorder = 0; whichorder <= HEROES; whichorder++)
  3067.     {   glory = -1;
  3068.         done = TRUE;
  3069.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3070.         {   if (hero[whichhero].alive && !hero[whichhero].moved)
  3071.             {   done = FALSE;
  3072.                 if
  3073.                 (   hero[whichhero].glory > glory
  3074.                  || (hero[whichhero].glory == glory && !(rand() % 2))
  3075.                 )
  3076.                 {   besthero = whichhero;
  3077.                     glory    = hero[whichhero].glory;
  3078.         }   }   }
  3079.         if (done)
  3080.         {   order[whichorder] = -1;
  3081.         } else
  3082.         {   order[whichorder] = besthero;
  3083.             hero[besthero].moved = TRUE;
  3084.     }   }
  3085.  
  3086.     for (whichorder = 0; whichorder <= HEROES; whichorder++)
  3087.     {   if (order[whichorder] == -1)
  3088.         {   break;
  3089.         } else
  3090.         {   move(order[whichorder]);
  3091.     }   }
  3092.  
  3093.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3094.     {   hero[whichhero].sea       = NORMAL;
  3095.         hero[whichhero].loseturn  = FALSE;
  3096.     }
  3097.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3098.     {   jarl[whichjarl].sea       = NORMAL;
  3099.         jarl[whichjarl].loseturn  = FALSE;
  3100.     }
  3101.     for (whichmonster = 0; whichmonster <= monsters; whichmonster++)
  3102.     {   monster[whichmonster].sea = NORMAL;
  3103. }   }
  3104.  
  3105. AGLOBAL void phase2(void)
  3106. {   SLONG whichorder;
  3107.  
  3108.     /* "2. COMBAT AND JARLS. Combat occurs in the same sequence as
  3109.         movement; jarls are recruited after combat.
  3110.  
  3111.         Heroes *must* attack at least one monster (if there is a monster)
  3112.         in the area they are in during the combat portion of the turn. If
  3113.         there is more than one monster they may choose which one they wish
  3114.         to fight. They may attack more than one monster in an area." */
  3115.  
  3116.     for (whichorder = 0; whichorder <= HEROES; whichorder++)
  3117.     {   if (order[whichorder] == -1)
  3118.         {   break;
  3119.         } else
  3120.         {   attack(order[whichorder]);
  3121. }   }   }
  3122.  
  3123. AGLOBAL void phase3(void)
  3124. {   FLAG  ok;
  3125.     SBYTE whichhero, whichcountry, whichjarl;
  3126.  
  3127.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3128.     {   if (hero[whichhero].control != NONE && !(hero[whichhero].verydead))
  3129.         /* Note that we even do this for dead heroes: they can keep their
  3130.            kingdoms (for now) where they have jarls, as they may be
  3131.            promoting a jarl, in which case they are allowed to keep their
  3132.            kingdoms. */
  3133.         {   for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  3134.             {   if (world[whichcountry].hero == whichhero)
  3135.                 {   // determine whether the hero or one of his jarls is there
  3136.  
  3137.                     ok = FALSE;
  3138.                     if (!world[whichcountry].is)
  3139.                     {   if (hero[whichhero].where == whichcountry)
  3140.                         {   ok = TRUE;
  3141.                             hero[whichhero].wealth += world[whichcountry].tax;
  3142.                             if (hero[whichhero].rune == GEOFU)
  3143.                             {   hero[whichhero].wealth++;
  3144.                         }   }
  3145.                         else
  3146.                         {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3147.                             {   if
  3148.                                 (   jarl[whichjarl].alive
  3149.                                  && jarl[whichjarl].hero == whichhero
  3150.                                  && jarl[whichjarl].where == whichcountry
  3151.                                 ) // taxes are given to the first friendly jarl found
  3152.                                 {   ok = TRUE;
  3153.                                     jarl[whichjarl].wealth += world[whichcountry].tax;
  3154.                                     if (hero[whichhero].rune == GEOFU)
  3155.                                     {   jarl[whichjarl].wealth++;
  3156.                                     }
  3157.                                     break;
  3158.                     }   }   }   }
  3159.  
  3160.                     if (!ok)
  3161.                     {   saywho(KINGDOM, whichcountry, FALSE, FALSE); // order-dependent
  3162.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_BEEN_OVERRUN, "has been overrun"));
  3163.                         strcat(saystring, ".");
  3164.                         say(LOWER);
  3165.                         world[whichcountry].hero = -1;
  3166.                         darken();
  3167.                         anykey();
  3168. }   }   }   }   }   }
  3169.  
  3170. MODULE SLONG odin_tyr(SLONG whichhero, FLAG attacking)
  3171. {   SLONG whichjarl, whichprayer;
  3172.     SLONG adjustment;
  3173.  
  3174.     if (hero[whichhero].god == ODIN)
  3175.     {   hero[whichhero].god = -1;
  3176.         whichprayer = d6();
  3177.  
  3178.         if (whichprayer == 1)
  3179.         {   adjustment = -3;
  3180.  
  3181.             sprintf
  3182.             (   saystring,
  3183.                 "Odin %s %s%s.",
  3184.                 GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO,                   "aids hero"),
  3185.                 hero[whichhero].name,
  3186.                 GetCatalogStr(li.li_Catalog, MSG_S_E_B_A_3_T_T_S,             "'s enemy by adding 3 to their strength")
  3187.             );
  3188.         } elif (whichprayer == 2)
  3189.         {   adjustment = -1;
  3190.  
  3191.             sprintf
  3192.             (   saystring,
  3193.                 "Odin %s %s%s.",
  3194.                 GetCatalogStr(li.li_Catalog, MSG_SENDS_A_WOLF_TO_AID_HERO,    "sends a wolf to aid hero"),
  3195.                 hero[whichhero].name,
  3196.                 GetCatalogStr(li.li_Catalog, MSG_S_ENEMY,                     "'s enemy")
  3197.             );
  3198.         } elif (whichprayer == 3)
  3199.         {   adjustment = 0;
  3200.  
  3201.             sprintf
  3202.             (   saystring,
  3203.                 "Odin%s.",
  3204.                 GetCatalogStr(li.li_Catalog, MSG_S_R_A_S_B_H_T_O_T_B,         "'s ravens are sent by him to observe the battle")
  3205.             );
  3206.         } elif (whichprayer == 4)
  3207.         {   adjustment = 1;
  3208.  
  3209.             sprintf
  3210.             (   saystring,
  3211.                 "Odin %s %s.",
  3212.                 GetCatalogStr(li.li_Catalog, MSG_SENDS_A_WOLF_TO_AID_HERO,    "sends a wolf to aid hero"),
  3213.                 hero[whichhero].name
  3214.             );
  3215.         } elif (whichprayer == 5)
  3216.         {   adjustment = 3;
  3217.  
  3218.             sprintf
  3219.             (   saystring,
  3220.                 "Odin %s %s %s.",
  3221.                 GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO,                   "aids hero"),
  3222.                 hero[whichhero].name,
  3223.                 GetCatalogStr(li.li_Catalog, MSG_BY_ADDING_3_TO_HIS_STRENGTH, "by adding 3 to his strength")
  3224.             );
  3225.         } else
  3226.         {   // assert(whichprayer == 6);
  3227.  
  3228.             adjustment = 5;
  3229.             hero[whichhero].glory += 3;
  3230.  
  3231.             sprintf
  3232.             (   saystring,
  3233.                 "Odin %s!",
  3234.                 GetCatalogStr(li.li_Catalog, MSG_INTERVENES_PERSONALLY,       "intervenes personally")
  3235.             );
  3236.         }
  3237.         say(LOWER);
  3238.         anykey();
  3239.     } elif (hero[whichhero].god == TYR)
  3240.     {   hero[whichhero].god = -1;
  3241.         whichprayer = d6();
  3242.  
  3243.         if (whichprayer == 1)
  3244.         {   adjustment = -1;
  3245.  
  3246.             sprintf
  3247.             (   saystring,
  3248.                 "Tyr %s %s%s.",
  3249.                 GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO,                   "aids hero"),
  3250.                 hero[whichhero].name,
  3251.                 GetCatalogStr(li.li_Catalog, MSG_S_E_B_A_1_T_T_S,             "'s enemy by adding 1 to their strength")
  3252.             );
  3253.         } elif (whichprayer == 2 || whichprayer == 3)
  3254.         {   adjustment = 0;
  3255.  
  3256.             sprintf
  3257.             (   saystring,
  3258.                 "Tyr %s.",
  3259.                 GetCatalogStr(li.li_Catalog, MSG_D_T_T_F_I_B_F,               "decides that the fight is balanced fairly")
  3260.             );
  3261.         } elif (whichprayer == 4)
  3262.         {   adjustment = 1;
  3263.  
  3264.             sprintf
  3265.             (   saystring,
  3266.                 "Tyr %s %s %s.",
  3267.                 GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO,                   "aids hero"),
  3268.                 hero[whichhero].name,
  3269.                 GetCatalogStr(li.li_Catalog, MSG_BY_ADDING_1_TO_HIS_STRENGTH, "by adding 1 to his strength")
  3270.             );
  3271.         } elif (whichprayer == 5)
  3272.         {   adjustment = 2;
  3273.  
  3274.             sprintf
  3275.             (   saystring,
  3276.                 "Tyr %s %s %s.",
  3277.                 GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO,                   "aids hero"),
  3278.                 hero[whichhero].name,
  3279.                 GetCatalogStr(li.li_Catalog, MSG_BY_ADDING_2_TO_HIS_STRENGTH, "by adding 2 to his strength")
  3280.             );
  3281.         } else
  3282.         {   // assert(whichprayer == 6);
  3283.  
  3284.             adjustment = 1; // for the hero himself
  3285.             if (attacking)
  3286.             {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3287.                 {   if (jarl[whichjarl].attacking)
  3288.                     {   adjustment++;
  3289.             }   }   }
  3290.             else
  3291.             {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3292.                 {   if (jarl[whichjarl].defending)
  3293.                     {   adjustment++;
  3294.             }   }   }
  3295.  
  3296.             sprintf
  3297.             (   saystring,
  3298.                 "Tyr %s %s %s.",
  3299.                 GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO,                   "aids hero"),
  3300.                 hero[whichhero].name,
  3301.                 GetCatalogStr(li.li_Catalog, MSG_B_A_1_T_T_S_O_E_P_O_H_S,     "by adding 1 to the strength of each person on his side")
  3302.             );
  3303.         }
  3304.         say(LOWER);
  3305.         anykey();
  3306.     } else
  3307.     {   adjustment = 0;
  3308.     }
  3309.     return(adjustment);
  3310. }
  3311.  
  3312. MODULE void pray(SLONG whichhero)
  3313. {   SLONG decision;
  3314.  
  3315.     decision = d6();
  3316.     if (decision == 1 || (hero[whichhero].rune == AMSIR && decision == 2))
  3317.     {   gods(whichhero);
  3318. }   }
  3319.  
  3320. MODULE void gods(SLONG whichhero)
  3321. {   SLONG whichgod, whichprayer, decision;
  3322.     FLAG  heard = FALSE;
  3323.  
  3324.     whichgod    = rand() % 6;
  3325.     whichprayer = d6();
  3326.  
  3327.     switch(whichgod)
  3328.     {
  3329.     case FREY:
  3330.         strcpy(saystring, "Frey ");
  3331.         if (whichprayer <= 4)
  3332.         {   // assert(whichprayer >= 1);
  3333.             hero[whichhero].maidens++;
  3334.  
  3335.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_W_S_A_M_T_H_H, "will send a maiden to heal hero"));
  3336.             strcat(saystring, " ");
  3337.             strcat(saystring, hero[whichhero].name);
  3338.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_NEXT_WOUND, "'s next wound"));
  3339.             strcat(saystring, ".");
  3340.         } else
  3341.         {   // assert(whichprayer == 5 || whichprayer == 6);
  3342.             hero[whichhero].maidens += 2;
  3343.  
  3344.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_W_S_A_M_T_H_H, "will send a maiden to heal hero"));
  3345.             strcat(saystring, " ");
  3346.             strcat(saystring, hero[whichhero].name);
  3347.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_NEXT_TWO_WOUNDS, "'s next two wounds"));
  3348.             strcat(saystring, ".");
  3349.         }
  3350.     break;
  3351.     case LOKI:
  3352.         strcpy(saystring, "Loki ");
  3353.         if (whichprayer <= 3)
  3354.         {   // assert(whichprayer >= 0);
  3355.  
  3356.             hero[whichhero].luck--;
  3357.             if (hero[whichhero].luck < 0)
  3358.             {   hero[whichhero].luck = 0;
  3359.             }
  3360.  
  3361.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_A_P_O_L_F_H, "steals a point of luck from hero"));
  3362.             strcat(saystring, " ");
  3363.             strcat(saystring, hero[whichhero].name);
  3364.             strcat(saystring, ".");
  3365.         } else
  3366.         {   // assert(whichprayer >= 4 && whichprayer <= 6);
  3367.  
  3368.             hero[whichhero].luck++;
  3369.  
  3370.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GRANTS_HERO, "grants hero"));
  3371.             strcat(saystring, " ");
  3372.             strcat(saystring, hero[whichhero].name);
  3373.             strcat(saystring, " ");
  3374.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_A_P_O_L_F_H_D, "a point of luck for his daring"));
  3375.             strcat(saystring, ".");
  3376.         }
  3377.     break;
  3378.     case NJORD:
  3379.         if (whichprayer == 1 || whichprayer == 2)
  3380.         {   hero[whichhero].sea = GOOD;
  3381.  
  3382.             sprintf
  3383.             (   saystring,
  3384.                 "Njord %s %s %s.",
  3385.                 GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"),
  3386.                 hero[whichhero].name,
  3387.                 GetCatalogStr(li.li_Catalog, MSG_TO_MOVE_BY_SEA_NEXT_TURN, "to move by sea next turn")
  3388.             );
  3389.         } elif (whichprayer == 3 || whichprayer == 4)
  3390.         {   decision = d6();
  3391.             hero[whichhero].wealth += decision;
  3392.  
  3393.             sprintf
  3394.             (   saystring,
  3395.                 "Njord %s %ld %s %s %s.",
  3396.                 GetCatalogStr(li.li_Catalog, MSG_GIVES, "gives"),
  3397.                 decision,
  3398.                 GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS_TO_HERO, "golden marks to hero"),
  3399.                 hero[whichhero].name,
  3400.                 GetCatalogStr(li.li_Catalog, MSG_AS_A_GIFT, "as a gift")
  3401.             );
  3402.         } elif (whichprayer == 5)
  3403.         {   decision = d6();
  3404.             if (decision > hero[whichhero].wealth)
  3405.             {   decision = hero[whichhero].wealth;
  3406.             }
  3407.             hero[whichhero].wealth -= decision;
  3408.  
  3409.             sprintf
  3410.             (   saystring,
  3411.                 "Njord %s %ld %s %s%s.",
  3412.                 GetCatalogStr(li.li_Catalog, MSG_TAKES, "takes"),
  3413.                 decision,
  3414.                 GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS_FROM_HERO, "golden marks from hero"),
  3415.                 hero[whichhero].name,
  3416.                 GetCatalogStr(li.li_Catalog, MSG_AS_DUE_TRIBUTE, "as due tribute")
  3417.             );
  3418.         } else
  3419.         {   // assert(whichprayer == 6);
  3420.             hero[whichhero].sea = BAD;
  3421.  
  3422.             sprintf
  3423.             (   saystring,
  3424.                 "Njord %s %s %s.",
  3425.                 GetCatalogStr(li.li_Catalog, MSG_PREVENTS_HERO, "prevents hero"),
  3426.                 hero[whichhero].name,
  3427.                 GetCatalogStr(li.li_Catalog, MSG_F_T_B_S_N_T, "from travelling by sea next turn")
  3428.             );
  3429.         }
  3430.     break;
  3431.     case ODIN:
  3432.         hero[whichhero].god = ODIN;
  3433.         heard = TRUE;
  3434.         strcpy(saystring, "Odin ");
  3435.     break;
  3436.     case THOR:
  3437.         hero[whichhero].god = THOR;
  3438.         heard = TRUE;
  3439.         strcpy(saystring, "Thor ");
  3440.     break;
  3441.     case TYR:
  3442.         hero[whichhero].god = TYR;
  3443.         heard = TRUE;
  3444.         strcpy(saystring, "Tyr ");
  3445.     break;
  3446.     default:
  3447.         // assert(0);
  3448.     break;
  3449.     }
  3450.     if (heard)
  3451.     {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HEARD_THE_PRAYER_OF_HERO, "heard the prayer of hero"));
  3452.         strcat(saystring, " ");
  3453.         strcat(saystring, hero[whichhero].name);
  3454.         strcat(saystring, ".");
  3455.     }
  3456.  
  3457.     say(LOWER);
  3458.     anykey();
  3459. }
  3460.  
  3461.  
  3462. MODULE void conquer(SLONG conquerortype, SLONG conqueror, SLONG conquerorhero, SLONG whichcountry)
  3463. {   /* This is order-dependent. We should say the message first before
  3464.     adjusting the world[] structure, otherwise we will get eg. "Hero
  3465.     Ragnar has conquered hero Ragnar's kingdom Upland (3).". */
  3466.  
  3467.     saywho(conquerortype, conqueror, FALSE, FALSE);
  3468.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_CONQUERED_KINGDOM, "has conquered"));
  3469.     saywho(KINGDOM, whichcountry, FALSE, TRUE);
  3470.     strcat(saystring, ".");
  3471.  
  3472.     world[whichcountry].hero = conquerorhero;
  3473.     darken();
  3474.  
  3475.     say(LOWER);
  3476.     anykey();
  3477. }
  3478.  
  3479. MODULE void findtreasure(SLONG victortype, SLONG victor, SLONG victorhero, SLONG whichmonster)
  3480. {   SLONG whichtreasure;
  3481.  
  3482.     for (whichtreasure = 0; whichtreasure <= treasures; whichtreasure++)
  3483.     {   if
  3484.         (   treasure[whichtreasure].possessortype == MONSTER
  3485.          && treasure[whichtreasure].possessor     == whichmonster
  3486.         )
  3487.         {   // give the treasure to the victor
  3488.             // assert(monster[whichmonster].species == DRAGON);
  3489.             treasure[whichtreasure].possessortype = victortype;
  3490.             treasure[whichtreasure].possessor     = victor;
  3491.             treasure[whichtreasure].where         = -1;
  3492.  
  3493.             saywho(victortype, victor, FALSE, FALSE);
  3494.             sprintf
  3495.             (   saystring2,
  3496.                 "%s %s!",
  3497.                 GetCatalogStr(li.li_Catalog, MSG_FINDS_THE, "finds the"),
  3498.                 treasure[whichtreasure].name
  3499.             );
  3500.             strcat(saystring, saystring2);
  3501.             say(LOWER);
  3502.             anykey();
  3503.     }   }
  3504.  
  3505.     if (monster[whichmonster].wealth > 0)
  3506.     {   hero[victorhero].wealth += monster[whichmonster].wealth;
  3507.  
  3508.         saywho(victortype, victor, FALSE, FALSE);
  3509.         sprintf
  3510.         (   saystring2,
  3511.             "%s %ld %s.",
  3512.             GetCatalogStr(li.li_Catalog, MSG_FINDS, "finds"),
  3513.             monster[whichmonster].wealth,
  3514.             GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks")
  3515.         );
  3516.         strcat(saystring, saystring2);
  3517.  
  3518.         monster[whichmonster].wealth = 0;
  3519.  
  3520.         say(LOWER);
  3521.         anykey();
  3522. }   }
  3523.  
  3524. MODULE void drop(SLONG droppertype, SLONG dropper, SLONG whichcountry)
  3525. {   SLONG whichsord, whichtreasure;
  3526.  
  3527.     for (whichtreasure = 0; whichtreasure <= treasures; whichtreasure++)
  3528.     {   if
  3529.         (   treasure[whichtreasure].possessortype == droppertype
  3530.          && treasure[whichtreasure].possessor     == dropper
  3531.         )
  3532.         {   // drop the treasure
  3533.             treasure[whichtreasure].possessortype = KINGDOM;
  3534.             treasure[whichtreasure].possessor     = -1;
  3535.             treasure[whichtreasure].where         = whichcountry;
  3536.             move_treasure(whichtreasure, TRUE);
  3537.     }   }
  3538.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  3539.     {   if
  3540.         (   sord[whichsord].possessortype == droppertype
  3541.          && sord[whichsord].possessor     == dropper
  3542.         )
  3543.         {   // drop the sword
  3544.             sord[whichsord].possessortype = KINGDOM;
  3545.             sord[whichsord].possessor     = -1;
  3546.             sord[whichsord].where         = whichcountry;
  3547.             move_sord(whichsord, TRUE);
  3548. }   }   }
  3549.  
  3550. MODULE FLAG islegal(SLONG movertype, SLONG mover, SLONG whichcountry, FLAG human)
  3551. {   if
  3552.     (   (   (movertype == HERO    && hero[mover].sea    == BAD)
  3553.          || (movertype == JARL    && jarl[mover].sea    == BAD)
  3554.          || (movertype == MONSTER && monster[mover].sea == BAD)
  3555.         )
  3556.      && (   world[whichcountry].type == SEA
  3557.          || world[whichcountry].type == ISLE
  3558.     )   )
  3559.     {   if (human)
  3560.         {   saywho(movertype, mover, FALSE, FALSE);
  3561.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
  3562.             strcat(saystring, ".");
  3563.             say(LOWER);
  3564.             anykey();
  3565.         }
  3566.         return(FALSE);
  3567.     } elif
  3568.     (   movertype              == MONSTER
  3569.      && monster[mover].species == SERPENT
  3570.      && world[whichcountry].type == LAND
  3571.     )
  3572.     {   return(FALSE);
  3573.     } else return(TRUE);
  3574. }
  3575.  
  3576. MODULE FLAG checkfree(SLONG whichhero, FLAG* freemove)
  3577. {   if (hero[whichhero].sea == GOOD)
  3578.     {   if (!(*(freemove)))
  3579.         {   if
  3580.             (   world[hero[whichhero].where].type == SEA
  3581.              || world[hero[whichhero].where].type == ISLE
  3582.             )
  3583.             {   *(freemove) = TRUE;
  3584.         }   }
  3585.         else
  3586.         {   if
  3587.             (   world[hero[whichhero].where].type == LAND
  3588.             )
  3589.             {   *(freemove) = FALSE;
  3590.             } else
  3591.             {   return(TRUE);
  3592.     }   }   }
  3593.     return(FALSE);
  3594. }
  3595.  
  3596.  
  3597. MODULE FLAG needitem(SLONG countertype, SLONG counter, SLONG whichcountry)
  3598. {   FLAG  needed = TRUE;
  3599.     SLONG which;
  3600.  
  3601.     for (which = 0; which <= SORDS; which++)
  3602.     {   if
  3603.         (   sord[which].possessortype == countertype
  3604.          && sord[which].possessor     == counter
  3605.         )
  3606.         {   needed = FALSE;
  3607.             break;
  3608.     }   }
  3609.     if (needed)
  3610.     {   for (which = 0; which <= SORDS; which++)
  3611.         {   if
  3612.             (   sord[which].possessortype == -1
  3613.              && sord[which].where         == whichcountry
  3614.             )
  3615.             {   return(TRUE);
  3616.     }   }   }
  3617.  
  3618.     for (which = 0; which <= treasures; which++)
  3619.     {   if
  3620.         (   treasure[which].possessortype == -1
  3621.          && treasure[which].where         == whichcountry
  3622.         )
  3623.         {   return(TRUE);
  3624.     }   }
  3625.  
  3626.     return(FALSE);
  3627. }
  3628.  
  3629. AGLOBAL SLONG getstrength(SLONG countertype, SLONG counter, FLAG defending)
  3630. {   SLONG strength = 0, // to avoid spurious compiler warnings,
  3631.           which;
  3632.  
  3633.     if (countertype == HERO)
  3634.     {   strength = hero[counter].strength;
  3635.     } elif (countertype == JARL)
  3636.     {   strength = jarl[counter].strength;
  3637.     } elif (countertype == MONSTER)
  3638.     {   strength = monster[counter].strength;
  3639.     } /* else assert(0); */
  3640.  
  3641.     for (which = 0; which <= SORDS; which++)
  3642.     {   if
  3643.         (   sord[which].possessortype == countertype
  3644.          && sord[which].possessor     == counter
  3645.         )
  3646.         {   if (which == BALMUNG || which == HRUNTING || which == LOVI)
  3647.             {   strength++;
  3648.             } else
  3649.             {   strength += 2;
  3650.             }
  3651.             break; // for speed
  3652.     }   }
  3653.  
  3654.     if (countertype != MONSTER && defending)
  3655.     {   for (which = 0; which <= treasures; which++)
  3656.         {   if
  3657.             (   treasure[which].possessortype == countertype
  3658.              && treasure[which].possessor     == counter
  3659.             )
  3660.             {   if (which == MAGICSHIRT)
  3661.                 {   strength++;
  3662.                 } elif (which == MAILCOAT)
  3663.                 {   strength += 2;
  3664.     }   }   }   }
  3665.  
  3666.     if (countertype == HERO && hero[counter].rune == OGAL)
  3667.     {   strength++;
  3668.     }
  3669.  
  3670.     if
  3671.     (   (countertype == HERO    &&    hero[counter].hagall)
  3672.      || (countertype == JARL    &&    jarl[counter].hagall)
  3673.      || (countertype == MONSTER && monster[counter].hagall)
  3674.     )
  3675.     {   strength--;
  3676.     }
  3677.  
  3678.     return(strength);
  3679. }
  3680. AGLOBAL SLONG getusualmoves(SLONG countertype, SLONG whichcounter)
  3681. {   SLONG moves = 0, // to avoid spurious compiler warnings
  3682.           which;
  3683.  
  3684.     if (countertype == HERO)
  3685.     {   moves = hero[whichcounter].moves;
  3686.     } elif (countertype == JARL)
  3687.     {   moves = jarl[whichcounter].moves;
  3688.     } elif (countertype == MONSTER)
  3689.     {   moves = monster[whichcounter].moves;
  3690.     } /* else assert(0); */
  3691.  
  3692.     if (countertype == HERO && hero[whichcounter].rune == EON)
  3693.     {   moves++;
  3694.     }
  3695.  
  3696.     if (countertype != MONSTER)
  3697.     {   for (which = 0; which <= treasures; which++)
  3698.         {   if
  3699.             (   treasure[which].possessortype == countertype
  3700.              && treasure[which].possessor     == whichcounter
  3701.             )
  3702.             {   if (which == MAGICSHIRT)
  3703.                 {   moves++;
  3704.                     break;
  3705.     }   }   }   }
  3706.  
  3707.     return(moves);
  3708. }
  3709.  
  3710. MODULE FLAG autosense(SLONG player)
  3711. {   SLONG whichcountry, i;
  3712.  
  3713.     for (whichcountry = 0; whichcountry <= 65; whichcountry++)
  3714.     {   // check for kingdom attacks
  3715.         if
  3716.         (   world[whichcountry].hero != player
  3717.          && world[whichcountry].tax
  3718.          && !world[whichcountry].is
  3719.         )
  3720.         {   if (findattackers(player, whichcountry, KINGDOM, whichcountry))
  3721.             {   return(TRUE);
  3722.         }   }
  3723.  
  3724.         // check for monster attacks
  3725.         for (i = 0; i <= monsters; i++)
  3726.         {   if
  3727.             (   monster[i].alive
  3728.              && monster[i].where == whichcountry
  3729.             )
  3730.             {   if (findattackers(player, whichcountry, MONSTER, i))
  3731.                 {   return(TRUE);
  3732.         }   }   }
  3733.  
  3734.         // check for hero attacks
  3735.         for (i = 0; i <= HEROES; i++)
  3736.         {   if
  3737.             (   player != i
  3738.              && hero[i].alive
  3739.              && hero[i].where == whichcountry
  3740.             )
  3741.             {   if (findattackers(player, whichcountry, HERO, i))
  3742.                 {   return(TRUE);
  3743.         }   }   }
  3744.  
  3745.         // check for jarl attacks
  3746.         for (i = 0; i <= JARLS; i++)
  3747.         {   if
  3748.             (   jarl[i].alive
  3749.              && jarl[i].where == whichcountry
  3750.              && jarl[i].hero != player
  3751.             )
  3752.             {   if (findattackers(player, whichcountry, JARL, i))
  3753.                 {   return(TRUE);
  3754.     }   }   }   }
  3755.  
  3756.     return(FALSE);
  3757. }
  3758.  
  3759. MODULE FLAG findattackers(SLONG player, SLONG whichcountry, SLONG victimtype, SLONG victim)
  3760. {   FLAG  able;
  3761.     SLONG whichattack, whichjarl;
  3762.  
  3763.     if
  3764.     (   hero[player].alive
  3765.      && hero[player].where == whichcountry
  3766.      && !hero[player].routed
  3767.     )
  3768.     {   able = TRUE;
  3769.  
  3770.         for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  3771.         {   if
  3772.             (   hero[player].attacktype[whichattack] == victimtype
  3773.              && hero[player].attacked[whichattack]   == victim
  3774.             )
  3775.             {   able = FALSE;
  3776.                 break; // for speed
  3777.         }   }
  3778.         if (able)
  3779.         {   return(TRUE); // for speed
  3780.     }   }
  3781.  
  3782.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3783.     {   if
  3784.         (   jarl[whichjarl].alive
  3785.          && jarl[whichjarl].hero == player
  3786.          && jarl[whichjarl].where == whichcountry
  3787.          && !jarl[whichjarl].routed
  3788.         )
  3789.         {   able = TRUE;
  3790.  
  3791.             for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  3792.             {   if
  3793.                 (   jarl[whichjarl].attacktype[whichattack] == victimtype
  3794.                  && jarl[whichjarl].attacked[whichattack]   == victim
  3795.                 )
  3796.                 {   able = FALSE;
  3797.                     break; // for speed
  3798.             }   }
  3799.             if (able)
  3800.             {   return(TRUE);
  3801.     }   }   }
  3802.  
  3803.     return(FALSE);
  3804. }
  3805.  
  3806. MODULE void deselect_combatants(SLONG attackhero, SLONG defendtype, SLONG defendhero, SLONG defender)
  3807. {   SLONG whichjarl;
  3808.  
  3809.     if (hero[attackhero].attacking)
  3810.     {   deselect_hero(attackhero, FALSE);
  3811.         hero[attackhero].attacking = FALSE;
  3812.     }
  3813.     if (defendhero != 1 && hero[defendhero].defending)
  3814.     {   deselect_hero(defendhero, FALSE);
  3815.         hero[defendhero].defending = FALSE;
  3816.     }
  3817.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3818.     {   if (jarl[whichjarl].attacking)
  3819.         {   deselect_jarl(whichjarl, FALSE);
  3820.             jarl[whichjarl].attacking   =
  3821.             jarl[whichjarl].recruitable = FALSE;
  3822.         } elif (jarl[whichjarl].defending)
  3823.         {   deselect_jarl(whichjarl, FALSE);
  3824.             jarl[whichjarl].defending   =
  3825.             jarl[whichjarl].recruitable = FALSE;
  3826.     }   }
  3827.     if (defendtype == MONSTER)
  3828.     {   deselect_monster(defender, FALSE);
  3829.     }
  3830.     refreshcounters();
  3831. }
  3832.  
  3833. MODULE SLONG assess_hero(SLONG whichhero, SLONG whichcountry)
  3834. {   SLONG good = 0,
  3835.           strength,
  3836.           whichjarl,
  3837.           whichmonster,
  3838.           whichrivalhero;
  3839.     FLAG  ok;
  3840.  
  3841.     if (whichcountry == -1)
  3842.     {   return(-100);
  3843.     }
  3844.  
  3845.     strength = getstrength(HERO, whichhero, TRUE);
  3846.  
  3847.     if (needitem(HERO, whichhero, whichcountry))
  3848.     {   good += 9; // gettable sword and/or treasure
  3849.     }
  3850.  
  3851.     if (countjarls(whichhero) < 4)
  3852.     {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3853.         {   if
  3854.             (   jarl[whichjarl].alive
  3855.              && jarl[whichjarl].hero  == -1
  3856.              && jarl[whichjarl].where == whichcountry
  3857.              && jarl[whichjarl].face  == FACEDOWN
  3858.              && hero[whichhero].luck  >= 1
  3859.             )
  3860.             {   good += 6; // recruitable jarl
  3861.     }   }   }
  3862.  
  3863.     for (whichrivalhero = 0; whichrivalhero <= HEROES; whichrivalhero++)
  3864.     {   if
  3865.         (   whichhero != whichrivalhero
  3866.          && hero[whichrivalhero].alive
  3867.          && hero[whichrivalhero].where == whichcountry
  3868.         )
  3869.         {   if (strength > checkdefenders_hero(whichrivalhero, whichcountry) + hero[whichrivalhero].luck)
  3870.             {   good += 5; // weak enemy hero
  3871.             } else
  3872.             {   good -= checkdefenders_hero(whichrivalhero, whichcountry); // strong enemy hero
  3873.     }   }   }
  3874.  
  3875.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3876.     {   if (jarl[whichjarl].alive)
  3877.         {   if
  3878.             (    jarl[whichjarl].face == FACEUP
  3879.              &&  jarl[whichjarl].hero != whichhero
  3880.              && (jarl[whichjarl].hero == -1 || hero[jarl[whichjarl].hero].where != whichcountry)
  3881.              &&  jarl[whichjarl].where == whichcountry
  3882.             )
  3883.             {   if (strength > checkdefenders_jarl(whichjarl, whichcountry) + 1)
  3884.                 {   good += 3; // weak enemy jarl
  3885.                 } else
  3886.                 {   good -= checkdefenders_jarl(whichjarl, whichcountry); // strong enemy jarl
  3887.             }   }
  3888.             elif (jarl[whichjarl].hero == whichhero)
  3889.             {   good += getstrength(JARL, whichjarl, TRUE); // encourage hero to stay with friendly jarls
  3890.     }   }   }
  3891.  
  3892.     for (whichmonster = 0; whichmonster <= monsters; whichmonster++)
  3893.     {   if
  3894.         (   monster[whichmonster].alive
  3895.          && monster[whichmonster].where == whichcountry
  3896.         )
  3897.         {   if (strength > monster[whichmonster].strength + 1)
  3898.             {   good += 4; // weak monster
  3899.             } else
  3900.             {   good -= monster[whichmonster].strength; // strong monster
  3901.     }   }   }
  3902.  
  3903.     if (whichcountry <= 35 && !world[whichcountry].is)
  3904.     {   if
  3905.         (   world[whichcountry].hero != whichhero
  3906.          && strength > world[whichcountry].tax + 2
  3907.         )
  3908.         {   good += 3; // weak kingdom
  3909.         } /* strong kingdom can't attack us, and we won't attack it, so no problem */
  3910.  
  3911.         if (world[whichcountry].hero == whichhero)
  3912.         {   // see whether we have any jarls here to run the kingdom for us
  3913.             ok = FALSE;
  3914.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3915.             {   if
  3916.                 (   jarl[whichjarl].alive
  3917.                  && jarl[whichjarl].hero  == whichhero
  3918.                  && jarl[whichjarl].where == whichcountry
  3919.                 )
  3920.                 {   ok = TRUE;
  3921.                     break; // for speed
  3922.             }   }
  3923.             if (!ok)
  3924.             {   good += world[whichcountry].tax; // encourage the hero to run his kingdom
  3925.     }   }   }
  3926.  
  3927.     good += (rand() % 4);
  3928.     return(good);
  3929. }
  3930.  
  3931. MODULE SLONG assess_jarl(SLONG whichjarl, SLONG whichcountry)
  3932. {   SLONG good = 0,
  3933.           strength,
  3934.           whichhero,
  3935.           whichmonster,
  3936.           whichrivalhero,
  3937.           whichrivaljarl;
  3938.     FLAG  ok;
  3939.  
  3940.     if (whichcountry == -1)
  3941.     {   return(-100);
  3942.     }
  3943.  
  3944.     whichhero = jarl[whichjarl].hero;
  3945.     strength = getstrength(JARL, whichjarl, TRUE);
  3946.  
  3947.     if (needitem(JARL, whichjarl, whichcountry))
  3948.     {   good += 9; // gettable sword and/or treasure
  3949.     }
  3950.  
  3951.     for (whichrivalhero = 0; whichrivalhero <= HEROES; whichrivalhero++)
  3952.     {   if
  3953.         (   hero[whichrivalhero].alive
  3954.          && hero[whichrivalhero].where == whichcountry
  3955.         )
  3956.         {   if (whichhero == whichrivalhero)
  3957.             {   good += getstrength(HERO, whichhero, TRUE); // encourage jarl to stay with friendly hero
  3958.             } else
  3959.             {   if (strength > checkdefenders_hero(whichrivalhero, whichcountry) + hero[whichrivalhero].luck)
  3960.                 {   good += 5; // weak enemy hero
  3961.                 } else
  3962.                 {   good -= checkdefenders_hero(whichrivalhero, whichcountry); // strong enemy hero
  3963.     }   }   }   }
  3964.  
  3965.     for (whichrivaljarl = 0; whichrivaljarl <= JARLS; whichrivaljarl++)
  3966.     {   if (whichrivaljarl != whichjarl && jarl[whichrivaljarl].alive)
  3967.         {   if
  3968.             (    jarl[whichrivaljarl].face == FACEUP
  3969.              &&  jarl[whichrivaljarl].hero != whichhero
  3970.              && (jarl[whichrivaljarl].hero == -1 || hero[jarl[whichrivaljarl].hero].where != whichcountry)
  3971.              &&  jarl[whichrivaljarl].where == whichcountry
  3972.             )
  3973.             {   if (strength > checkdefenders_jarl(whichrivaljarl, whichcountry) + 1)
  3974.                 {   good += 3; // weak enemy jarl
  3975.                 } else
  3976.                 {   good -= checkdefenders_jarl(whichrivaljarl, whichcountry); // strong enemy jarl
  3977.             }   }
  3978.             elif (jarl[whichrivaljarl].hero == whichhero)
  3979.             {   good += getstrength(JARL, whichrivaljarl, TRUE); // encourage jarl to stay with friendly jarls
  3980.     }   }   }
  3981.  
  3982.     for (whichmonster = 0; whichmonster <= monsters; whichmonster++)
  3983.     {   if
  3984.         (   monster[whichmonster].alive
  3985.          && monster[whichmonster].where == whichcountry
  3986.         )
  3987.         {   if (strength > monster[whichmonster].strength + 1)
  3988.             {   good += 4; // weak monster
  3989.             } else
  3990.             {   good -= monster[whichmonster].strength; // strong monster
  3991.     }   }   }
  3992.  
  3993.     if (whichcountry <= 35 && !world[whichcountry].is)
  3994.     {   if
  3995.         (   world[whichcountry].hero != whichhero
  3996.          && strength > world[whichcountry].tax + 2
  3997.         )
  3998.         {   good += 3; // weak kingdom
  3999.         } /* strong kingdom can't attack us, and we won't attack it, so no problem */
  4000.  
  4001.         if (world[whichcountry].hero == whichhero)
  4002.         {   // see whether we have a hero here to run the kingdom for us
  4003.             if (hero[whichhero].where == whichcountry)
  4004.             {   ok = TRUE;
  4005.             } else
  4006.             {   // see whether we have any other jarls here to run the kingdom for us
  4007.                 ok = FALSE;
  4008.                 for (whichrivaljarl = 0; whichrivaljarl <= JARLS; whichrivaljarl++)
  4009.                 // they are actually allies, not rivals, of course, but this is more efficient
  4010.                 {   if
  4011.                     (   whichrivaljarl != whichjarl
  4012.                      && jarl[whichrivaljarl].alive
  4013.                      && jarl[whichrivaljarl].hero  == whichhero
  4014.                      && jarl[whichrivaljarl].where == whichcountry
  4015.                     )
  4016.                     {   ok = TRUE;
  4017.                         break; // for speed
  4018.             }   }   }
  4019.             if (!ok)
  4020.             {   good += world[whichcountry].tax; // encourage the jarl to run his hero's kingdom
  4021.     }   }   }
  4022.  
  4023.     good += (rand() % 4);
  4024.     return(good);
  4025. }
  4026.  
  4027. MODULE SLONG countjarls(SLONG whichhero)
  4028. {   SLONG jarls = 0,
  4029.           whichjarl;
  4030.  
  4031.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4032.     {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  4033.         {   {   jarls++;
  4034.     }   }   }
  4035.     return(jarls);
  4036. }
  4037.  
  4038. MODULE void onemove_hero(SLONG whichhero, SLONG whichcountry)
  4039. {   unslot_hero(whichhero);
  4040.     hero[whichhero].where = whichcountry;
  4041.  
  4042. #ifdef QUICKMOVES
  4043.     if (hero[whichhero].control == HUMAN)
  4044.     {   move_hero(whichhero, TRUE);
  4045.     } else
  4046.     {   // assert(hero[whichhero].control == AMIGA);
  4047.         move_hero(whichhero, FALSE);
  4048.     }
  4049. #else
  4050.     move_hero(whichhero, TRUE);
  4051. #endif
  4052.  
  4053.     world[hero[whichhero].where].visited = TRUE;
  4054.     if (whichrealmove <= 65)
  4055.     {   movearray[whichrealmove++] = hero[whichhero].where;
  4056.     }
  4057.     if (!(checkfree(whichhero, &freemove)))
  4058.     {   whichmove++;
  4059. }   }
  4060. MODULE void onemove_jarl(SLONG whichjarl, SLONG whichcountry)
  4061. {   unslot_jarl(whichjarl);
  4062.     jarl[whichjarl].where = whichcountry;
  4063.  
  4064. #ifdef QUICKMOVES
  4065.     if (hero[jarl[whichjarl].hero].control == HUMAN)
  4066.     {   move_jarl(whichjarl, TRUE);
  4067.     } else
  4068.     {   // assert(hero[jarl[whichjarl].hero].control == AMIGA);
  4069.         move_jarl(whichjarl, FALSE);
  4070.     }
  4071. #else
  4072.     move_jarl(whichjarl, TRUE);
  4073. #endif
  4074.  
  4075.     world[jarl[whichjarl].where].visited = TRUE;
  4076.     movearray[whichmove++] = jarl[whichjarl].where;
  4077. }
  4078.  
  4079. MODULE SLONG checkdefenders_hero(SLONG whichhero, SLONG whichcountry)
  4080. {   SLONG strength,
  4081.           whichjarl;
  4082.  
  4083.     strength = getstrength(HERO, whichhero, TRUE);
  4084.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4085.     {   if
  4086.         (   jarl[whichjarl].hero  == whichhero
  4087.          && jarl[whichjarl].where == whichcountry
  4088.         )
  4089.         {   strength += getstrength(JARL, whichjarl, TRUE);
  4090.     }   }
  4091.  
  4092.     return(strength);
  4093. }
  4094. MODULE SLONG checkdefenders_jarl(SLONG whichjarl, SLONG whichcountry)
  4095. {   SLONG strength,
  4096.           whichalliedjarl,
  4097.           whichhero;
  4098.  
  4099.     strength  = getstrength(JARL, whichjarl, TRUE);
  4100.     whichhero = jarl[whichjarl].hero;
  4101.     if (whichhero != -1)
  4102.     {   if (hero[whichhero].where == whichcountry)
  4103.         {   strength += getstrength(HERO, whichhero, TRUE);
  4104.         }
  4105.         for (whichalliedjarl = 0; whichalliedjarl <= JARLS; whichalliedjarl++)
  4106.         {   if
  4107.             (   whichjarl != whichalliedjarl
  4108.              && jarl[whichalliedjarl].hero  == whichhero
  4109.              && jarl[whichalliedjarl].where == whichcountry
  4110.             )
  4111.             {   strength += getstrength(JARL, whichjarl, TRUE);
  4112.     }   }   }
  4113.  
  4114.     return(strength);
  4115. }
  4116.  
  4117. MODULE void givegold(SLONG whichhero, SLONG whichjarl)
  4118. {   if (jarl[whichjarl].wealth)
  4119.     {   saywho(JARL, whichjarl, FALSE, FALSE);
  4120.         if (hero[whichhero].where == jarl[whichjarl].where)
  4121.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GIVES, "gives"));
  4122.         } else
  4123.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GAVE, "gave"));
  4124.         }
  4125.         strcat(saystring, " ");
  4126.         stcl_d(numberstring, jarl[whichjarl].wealth);
  4127.         strcat(saystring, numberstring);
  4128.         strcat(saystring, " ");
  4129.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS_TO_HERO, "golden marks to hero"));
  4130.         strcat(saystring, " ");
  4131.         strcat(saystring, hero[whichhero].name);
  4132.         strcat(saystring, ".");
  4133.  
  4134.         hero[whichhero].wealth += jarl[whichjarl].wealth;
  4135.         jarl[whichjarl].wealth = 0;
  4136.  
  4137.         say(LOWER);
  4138.         anykey();
  4139. }   }
  4140.